Skip to navigation

Enforcement

Enforcement

Enforcement adds three gate capabilities for tenant agents and CI pipelines:

  1. Credential vault — envelope-encrypted API keys (Stripe only in Phase 1).
  2. Gated execution — single-use leases that call a fixed upstream host with a vaulted credential.
  3. CI attestation — signed writ scan manifests and per-repo drift.

These endpoints are tenant-facing and documented here. Portal-only endpoints (vault enrollment and revocation, which require a signed-in session + TOTP) are internal and omitted.


Credential vault

The vault stores one credential per enrolled system per tenant. Phase 1 supports Stripe only (systemId: stripe).

  • Credentials are envelope-encrypted with AWS KMS GenerateDataKey and an encryption context {tenant_id, system_id}.
  • The plaintext credential exists only in gate memory at execute time.
  • After enrollment the API key is never displayed or returned again.
  • Revocation sets the credential status to revoked and burns outstanding leases.

Enroll and revoke are portal-only actions: sign in at https://app.withwrit.com, go to Enforcement, and confirm with your authenticator app.


Gated execution

1. Get an ALLOW token

Your agent calls POST /v1/check as usual. An ALLOW response contains an authToken bound to the exact write.

curl -X POST https://api.withwrit.com/v1/check \
-H "Authorization: Bearer $WRIT_KEY" \
-H "Content-Type: application/json" \
-d '{
"sponsorId": "acme",
"agentId": "refunds-agent",
"verb": "refund",
"target": "order-1001",
"purpose": "refund duplicate charge"
}'

2. Create a lease

Convert the ALLOW token into a single-use lease bound to the exact Stripe request you intend to send. The lease TTL is capped to the token’s remaining life (≤ 90 seconds).

curl -X POST https://api.withwrit.com/v1/leases \
-H "Authorization: Bearer $WRIT_KEY" \
-H "Content-Type: application/json" \
-d '{
"token": "$AUTH_TOKEN",
"method": "POST",
"path": "/v1/refunds",
"body": {"charge": "ch_3N..."}
}'

3. Execute

Call POST /v1/execute with the lease id and the same method/path/body.

curl -X POST https://api.withwrit.com/v1/execute \
-H "Authorization: Bearer $WRIT_KEY" \
-H "Content-Type: application/json" \
-d '{
"leaseId": "$LEASE_ID",
"systemId": "stripe",
"method": "POST",
"path": "/v1/refunds",
"body": {"charge": "ch_3N..."},
"idempotencyKey": "refund-order-1001"
}'

The gate returns Stripe’s status and body verbatim. If the lease is expired, reused, the request bytes don’t match, or the credential is revoked, the gate fails closed: no upstream call, and an error receipt.

Constraints

  • systemId must be stripe in Phase 1.
  • path must begin with /v1/.
  • body must be JSON and ≤ 1 MB.
  • No streaming, no multipart, no arbitrary URLs.

CI attestation

writ scan can emit a signed manifest for CI.

Fetch the manifest key

Issue once per tenant:

writ manifest-key --key $WRIT_KEY

Store the returned key in CI as WRIT_MANIFEST_KEY.

Produce a signed manifest

writ scan --manifest-out manifest.json --key $WRIT_KEY

The manifest includes:

  • repoId
  • commitSha
  • scannerVersion
  • per-language findings summary
  • ungated write-sites (path + verb)
  • policyFileHash
  • timestamp

It is signed with HMAC-SHA256 over the canonical JSON.

Submit the manifest

curl -X POST https://api.withwrit.com/v1/manifests \
-H "Authorization: Bearer $WRIT_KEY" \
-H "Content-Type: application/json" \
-d @manifest-payload.json

where manifest-payload.json is:

{
"repoId": "myrepo",
"manifest": { ... },
"signature": "..."
}

The gate verifies the signature, stores the manifest, and returns drift vs the previous manifest:

  • newUngatedSites
  • resolvedSites
  • policyHashChanged
  • scannerVersionChanged

View the latest manifest and drift in the portal under Enforcement, or via GET /v1/manifests and GET /v1/manifests/{repoId}.


API reference

See the Enforcement endpoints in the API reference:

  • POST /v1/leases
  • POST /v1/execute
  • GET /v1/manifest-key
  • POST /v1/manifests
  • GET /v1/manifests
  • GET /v1/manifests/{repoId}