VXP docs · draft 0.1

Security, errors, recovery and versions

The threats VXP addresses and the ones it does not, every error code, how operations recover from failures, and how keys and versions evolve.

Threats#

ThreatHow VXP covers it
Forgery by an outsiderSignatures, RFC 7638 kid, and keys anchored to the company's issuer ([[issuer-anchoring§10 anchoring]])
Terms changed after approvalThe terms digest covers summary and terms; approval and execution must cite it (P1)
Replay into another operation or to another agentop, seq, prev, aud and user equal across the chain, verified
Two contradictory successes on one resourceA precondition before executing and one operation in progress per resource (O6, I2); across separate packages, only a log with witnesses, which 0.1 specifies but no verifier grants yet
Another agent or user rewrites an operationThe full owner on every reuse (ID3)
“The user approved”, said by the agentLabeled agent_asserted, with its real root (P2, P7)
The company lies about its own systemNo signature solves this. VXP relies on read-back, third-party evidence and an honest level label
The operator signs a whole alternative chainPossible while the operator holds the keys and there are no witnesses: the verifier says single_root: operator

Full table: §9 security.

Errors#

WhereCodes
Requestsidempotency_key_required, invalid_request, target_not_found, idempotency_key_reused, request_exists, resource_busy, request_not_found, authorization_required
Proposalsterms_changed, proposal_expired, proposal_not_acceptable, attempt_limit_exceeded, counter_rejected, negotiation_limit_exceeded
Authorizationinvalid_authorization_details, and invalid_target on a native-only gateway
Relationshiprelationship_not_found, relationship_revoked, relationship_expired, action_not_authorized, relationship_limit_exceeded, target_not_found
Closed questionsalert_not_found, already_answered, alert_expired, option_not_allowed
VerifierThe codes of the chain rules, plus issuer_not_anchored and the PACT receipt codes

Someone else's resource and a missing one answer the same way, so an error never confirms that something exists (O3). Full table: §9 errors.

Recovery#

  • The response is lost. Repeat the request with the same Idempotency-Key: you get the same request, never a second operation. Accepting a revision twice runs it once (§8 idempotency, O6).
  • It is not known whether the effect happened. The operation stays pending_verification, never failed. The company signs unknown. A later read reconciles without repeating the action, and a correction records what became known (P3, P4).
  • The system contradicts the terms. The read-back says so, the result stays unknown, the operation waits for a person, and nothing is retried (P5).
  • Cancelling during execution is a request to stop. It never claims a reversal that was not read back (§8 cancellation).
  • The company's server restarts. With persistent keys, earlier proofs still verify.

Keys#

  • Persist proof keys. Rotate by publishing the new key and keeping the earlier one in the JWKS. Never reuse a retired key (§10 key rotation).
  • The relationship key is distinct from the proof keys and from any Poppy or PACT key (R5).
  • The reference implementation keeps keys in VXP_KEYS_DIR. Without it, they live in memory and die with the process, and every proof they signed becomes impossible to check unless its public material was saved (§10 key rotation).

Privacy#

Personal data travels only as selective disclosures. user is a per-company pseudonym. Keys, issuers and log tags are per company, and the log keeps no personal data (§9 privacy).

Versions#

Draft versions are incompatible with each other until 1.0, and a verifier rejects a v it does not know. See Specification and versions and the changelog.

Reporting a vulnerability#

Privately, through the repository's Security tab. See SECURITY.md.