Security model

VCP is designed around explicit privacy boundaries. This page sets out the controls that exist today, what each one can and cannot guarantee, and what any system that receives VCP context must enforce for itself.

Core security principles

Data minimization

VCP is designed to transmit the minimum needed. Private details become boolean flags — platforms see budget_limited: true, not your financial situation.

User control

You decide which consent-required fields each platform receives, and you can revoke that consent. Private details are never shared, consent or not. The yes/no constraint flags derived from them, such as time_limited, go to every platform.

Auditable sharing

The reference library can log each sharing event with the platform, the time, and the fields shared and withheld. This site's pages do not call it, so the log in the Campion demo is a scripted example.

Privacy levels

Every piece of context in VCP has a privacy level that determines how it can be shared.

Public Shareable

Information you're comfortable sharing with any platform. Examples: learning goals, experience level, general preferences.

goal: "learn_guitar" experience: "beginner"
Private Never shared

Sensitive context that is never shared, even with consent. It shapes what platforms see only through yes/no constraint flags.

health_conditions: [LOCAL ONLY] → energy_variable: true

How privacy flags work

The core mechanism: your private circumstances become simple boolean flags.

Your private context

What you know:
  • "I live in an apartment with thin walls"
  • "My neighbor works night shifts"
  • "I can't make loud noise after 9pm"
VCP converts this to

What platforms see

noise_restricted: true No context, no details, just the flag

The platform knows to recommend quiet practice methods. It has no idea why you need them, and it doesn't need to know.

Trust boundaries

Different stakeholders get different views of your context.

You Full context, all details
VCP application Processes context, applies privacy rules
Platforms See public fields, what you've consented to, and constraint flags

HR sees:

  • Career goal: Tech Lead
  • Mandatory training: on track
  • Training budget use: within policy

HR doesn't see:

  • Why you need flexible scheduling
  • Health circumstances
  • Personal situation details

Technical implementation

Token format

Context is encoded into CSM-1 (Constitutional Safety Minicode) tokens. Private-context values never enter the token, which records only that private context is present. Personal state is carried on the token's R-line whenever it is set.

No central storage

VCP is designed so private context can stay on your devices unless a separate integration explicitly documents storage or sync. This site's chat sends your message, the page's constitution ID, persona and constraint flags to this site's server, plus the page's personal state if you tick the chat's sharing box. The server stores none of it. When a live model is configured, it forwards the message, constitution ID, persona and flags to the model provider, with personal state reduced to a protection level. We can't leak what we don't have.

Open specification

The VCP specification is open for inspection. You can read its privacy rules and test an implementation against them. An open specification does not vouch for any particular deployment, so you still need to evaluate that deployment's code, configuration, operators, storage, and downstream services.

Transport security (VCP/T)

VCP/T defines how constitution bundles are signed and verified. A conforming application must enforce a verify-then-inject boundary so rejected or unsigned bundle content cannot reach the model through that path.

Signed bundles

Every schema-conforming constitution bundle carries a supported digital signature. The manifest names the signing key, but that claim is untrusted input until the key matches a valid trust anchor (a key configured independently for that issuer) and the signature verifies against it.

Content-addressed storage

Content is hashed with SHA-256. The hash is embedded in the signed manifest, binding the signature to the exact bytes. A tampered file hashes to a different value, so verification fails.

Verify-then-inject

Signature verification must pass before content reaches the LLM. If verification fails, the bundle is rejected and the request fails closed — no fallback to unsigned content.

Temporal claims

Each manifest records when it was issued (iat), when it becomes valid (nbf), when it expires (exp), and a unique ID (jti). A bundle outside its validity window is rejected, and so is one whose ID has already been accepted.

Verify-then-inject flow

The orchestrator is the part of the application that fetches constitution bundles and assembles the model's prompt. It injects a bundle's text only after the bundle passes verification. The main checks are shown below; the SDK also checks size limits, schema, issuer and auditor trust, safety attestation, scope and a content safety scan.

Repository
Orchestrator
LLM
1 Fetch bundle
manifest.json + content.txt
2 Check SHA-256 content hash
3 Verify Ed25519 signature
4 Check revocation, where the manifest configures it
5 Check validity window and jti replay
6 Enforce token budget
7 Log to audit trail
8 Inject verified text
9 Apply constitution

Threat model

VCP/T is designed to mitigate specific, enumerated threats. Some defenses are built into the protocol; others, such as pinning bundle versions or responding to a stolen signing key, are duties of the application or its operator.

Prompt injection via constitution

Attacker modifies constitution content to inject malicious instructions.

Defense The signed SHA-256 hash detects modification. It does not make the content safe, because a signature can faithfully preserve malicious content. Review, scanning, prompt delimiting, and model-side boundaries remain separate defenses.

Replay attacks

Attacker re-submits a previously valid but now-stale bundle.

Defense Temporal claims (iat/nbf/exp) reject bundles outside their validity window, and unique jti tracking rejects duplicates.

Context overflow

Oversized constitution monopolizes the LLM's context window.

Defense Token budget enforcement. The manifest declares a max_tokens limit, and the orchestrator enforces it before injection.

Key compromise

Author's signing key is stolen or leaked.

Defense Remove the compromised key from the trust anchors, rotate it through a controlled release, revoke each affected bundle's jti where the manifest configures revocation, and investigate every accepted use of the key.

Downgrade attacks

Attacker substitutes an older, weaker version of a constitution.

Defense Your application must pin the bundle identities and versions it accepts. Capability negotiation checks only protocol compatibility, and the current bundle orchestrator keeps no minimum-version registry, so it will not enforce a minimum version for you.

Fail-open risk

Verification error silently allows unsigned content through.

Defense Keep formatting and model invocation reachable only from the verified branch. Define any cached or restricted fallback as a separate reviewed path, never as silent acceptance of the rejected bundle.

Personal state privacy

The personal tier, encoded on the CSM-1 R-line, carries real-time personal state: cognitive state, emotional tone, energy level, perceived urgency, and body signals. These dimensions need the strongest protection, so the specification requires the line to be stripped before transmission unless the user consents.

Stripped before transmission

This site keeps demo state in page memory, and its chat never sends private fields. The chat sends the page's personal state only if you tick its sharing box. Whether it comes from the chat or another caller, this site's server reduces personal state to a protection level before any model sees it. The token encoder writes the R-line whenever state is set, so an application that transmits tokens must strip that line unless the user has consented. Other implementations must enforce an equivalent boundary.

Flags for private context

The privacy filter reduces private context to coarse boolean flags such as energy_variable: true and withholds the underlying condition. Applications must send that filtered projection rather than serializing the full source object. Personal state is not reduced to flags; on the R-line each dimension carries a value and an intensity from 1 to 5.

Signal decay

Personal state decays. Each dimension's intensity halves toward a neutral baseline on its own schedule (12 minutes for cognitive state, up to 4 hours for body signals), so old state carries less weight. Pinned dimensions do not decay, and decay never deletes the value. The specification recommends that applications purge expired signals within 24 hours of expiry.

Explicit consent

Sharing personal state with any platform requires explicit, revocable consent. In this demo, one checkbox in each chat sends the page's whole personal state or none of it. The VCP/A draft recommends per-dimension choice, but SDK 4.2.0 and this site do not implement it yet.

Report a security issue

Do not open a public GitHub issue for a suspected vulnerability. Email security@creedspace.com instead; the site's source repository is private and has no public advisory form. Include safe reproduction steps, the affected route or component, and the build ID of the deployment you tested (the /api/health/live endpoint reports it). Do not send live credentials, personal data, or third-party secrets.

We aim to acknowledge reports within 4 hours for critical issues, 1 business day for high, 3 business days for medium, and 5 business days for low severity. These are interim targets, not a service-level agreement. The full severity, embargo, and disclosure process is set out in the VCP coordinated security response.

The current contact, policy, and expiry are also published in security.txt.

See privacy in action

Follow one person through a workday as the same context shapes different views at work and at home.