Skip to content

Latest commit

 

History

History
307 lines (225 loc) · 10.6 KB

File metadata and controls

307 lines (225 loc) · 10.6 KB

Multi-Tenant Receipt Isolation Guide

Version: 0.1 Since: v0.11.3 Design Decision: DD-149

This guide describes three tiers of receipt isolation for multi-tenant PEAC deployments. Each tier trades simplicity for stronger isolation between tenants.

Overview

Multi-tenant platforms that issue PEAC receipts on behalf of multiple tenants need to decide how to isolate receipt signing keys and issuer identities. The choice affects:

  • Key compromise blast radius: How many tenants are affected if a signing key is compromised
  • Cross-tenant receipt visibility: Whether one tenant's receipts can be correlated with another's
  • Operational complexity: Key management overhead per tier
  • Verifier requirements: What verifiers need to discover and validate receipts

Tier 1: Shared (Simplest)

Architecture

All tenants share a single JWKS, a single signing key, and a single iss origin.

Issuer: https://platform.example
JWKS:   https://platform.example/.well-known/jwks.json
Keys:   1 active key (kid: "prod-2026-03")

All tenant receipts are signed with the same key and carry the same iss:

{
  "iss": "https://platform.example",
  "sub": "agent:tenant-abc/service-v2",
  "iat": 1709000000,
  "jti": "rcpt_01HQXYZ123456789"
}

Tenant isolation relies on the sub claim or an extension:

{
  "ext": [
    {
      "key": "org.peacprotocol/tenant_ref",
      "value": { "tenant_id": "tenant-abc" }
    }
  ]
}

Characteristics

Property Value
Key management Single key to rotate
Blast radius All tenants affected by key compromise
Cross-tenant correlation Trivial (same iss and kid)
Verifier setup Single issuer config to discover
Operational cost Minimal

When to Use

  • Internal multi-tenant services where tenants trust the platform
  • Development and staging environments
  • Low-sensitivity receipt types (non-financial, non-identity)

Security Considerations

  • A compromised key affects all tenants; emergency revocation requires rotating the shared key
  • Tenants can observe each other's receipt volume and timing patterns via the shared iss
  • No cryptographic boundary between tenants; isolation is purely logical

Tier 2: Scoped (Balanced)

Architecture

All tenants share a single JWKS and a single iss origin, but each tenant gets a dedicated signing key with a tenant-prefixed kid.

Issuer: https://platform.example
JWKS:   https://platform.example/.well-known/jwks.json
Keys:
  - kid: "tenant-abc/prod-2026-03" (active, for tenant-abc)
  - kid: "tenant-def/prod-2026-03" (active, for tenant-def)
  - kid: "tenant-abc/prod-2026-02" (deprecated, grace period)

Receipts carry the tenant-scoped kid in the JWS header:

{
  "header": {
    "alg": "EdDSA",
    "kid": "tenant-abc/prod-2026-03"
  },
  "payload": {
    "iss": "https://platform.example",
    "sub": "agent:service-v2",
    "iat": 1709000000,
    "jti": "rcpt_01HQXYZ123456789"
  }
}

Key Naming Convention

Tenant-prefixed kid values use the format:

{tenant_id}/{environment}-{date}

Examples:

  • tenant-abc/prod-2026-03
  • acme-corp/staging-2026-03
  • org-42/prod-2026-02 (deprecated key in grace period)

Characteristics

Property Value
Key management One key per tenant (more keys, single JWKS)
Blast radius Single tenant affected by key compromise
Cross-tenant correlation Moderate (same iss, different kid)
Verifier setup Single issuer config; verifiers select key by kid
Operational cost Moderate (key rotation per tenant)

When to Use

  • SaaS platforms with moderate isolation requirements
  • Multi-tenant APIs where each tenant needs independent key rotation
  • Environments where a single iss simplifies verifier configuration

Security Considerations

  • Key compromise affects only one tenant; revoke the tenant-specific key without affecting others
  • Tenants share the same iss; verifiers cannot distinguish tenants by issuer alone (must inspect kid)
  • kid collision risk: ensure tenant IDs are unique and stable; platforms MUST NOT reuse tenant IDs after deletion
  • JWKS document grows linearly with tenant count; enforce maxJwksKeys limits (default: 20 per VERIFIER-SECURITY-MODEL.md). Platforms with more than 20 active tenants SHOULD use Tier 3

Key Rotation

Each tenant key rotates independently per KEY-ROTATION.md:

  1. Add new key: kid: "tenant-abc/prod-2026-04" (PENDING)
  2. Activate new key; deprecate old: kid: "tenant-abc/prod-2026-03" (DEPRECATED)
  3. After 30-day overlap: retire old key

The platform MUST coordinate Cache-Control max-age on the shared JWKS with the shortest tenant overlap period.


Tier 3: Isolated (Strongest)

Architecture

Each tenant gets a dedicated JWKS, a dedicated iss origin, and a dedicated peac-issuer.json configuration.

Tenant ABC:
  Issuer: https://tenant-abc.platform.example
  Config: https://tenant-abc.platform.example/.well-known/peac-issuer.json
  JWKS:   https://tenant-abc.platform.example/.well-known/jwks.json
  Keys:   kid: "prod-2026-03"

Tenant DEF:
  Issuer: https://tenant-def.platform.example
  Config: https://tenant-def.platform.example/.well-known/peac-issuer.json
  JWKS:   https://tenant-def.platform.example/.well-known/jwks.json
  Keys:   kid: "prod-2026-03"

Receipts carry the tenant-specific iss:

{
  "iss": "https://tenant-abc.platform.example",
  "sub": "agent:service-v2",
  "iat": 1709000000,
  "jti": "rcpt_01HQXYZ123456789"
}

Characteristics

Property Value
Key management Fully independent per tenant
Blast radius Single tenant only
Cross-tenant correlation Difficult (different iss origins)
Verifier setup Separate discovery per tenant
Operational cost High (per-tenant DNS, TLS certificates, JWKS hosting)

When to Use

  • Enterprise deployments with strict isolation requirements
  • Regulated environments (financial services, healthcare)
  • Platforms where tenants need fully independent verifier discovery
  • Compliance scenarios requiring per-tenant audit boundaries

Implementation Options

Subdomain model (recommended):

https://{tenant}.platform.example
  • Wildcard TLS certificate simplifies provisioning
  • DNS-level isolation
  • Each subdomain hosts its own /.well-known/peac-issuer.json

Path-based model (NOT recommended):

https://platform.example/tenants/{tenant}
  • Violates origin-only semantics (issuer iss should be an origin, not a path)
  • Breaks peac-issuer.json discovery (which derives from origin only)
  • Creates ambiguity in issuer matching

Security Considerations

  • Strongest isolation: no shared keys, no shared issuer identity
  • Key compromise is fully contained to the affected tenant
  • Verifiers discover keys independently per tenant; no cross-tenant JWKS leakage
  • Higher operational cost: TLS cert management, DNS provisioning, per-tenant monitoring

Migration Between Tiers

Tier 1 to Tier 2

  1. Generate per-tenant keys with tenant-prefixed kid values
  2. Add new keys to the shared JWKS
  3. Update receipt signing to use the tenant-specific key
  4. After overlap period, remove the shared key
  5. No change to iss or peac-issuer.json

Tier 2 to Tier 3

  1. Provision per-tenant subdomains and TLS certificates
  2. Create per-tenant peac-issuer.json at each subdomain
  3. Create per-tenant JWKS at each subdomain
  4. Update receipt signing: change iss to tenant-specific origin
  5. During migration: maintain old iss receipts in the shared JWKS for the overlap period
  6. After overlap: remove tenant keys from the shared JWKS

Breaking change warning: Changing iss invalidates all in-flight receipts. Verifiers that cached the old issuer will fail verification until they discover the new issuer. Plan a migration window and communicate with verifiers.

Tier 3 to Tier 2

Not recommended. Merging isolated issuers into a shared issuer loses isolation guarantees and may confuse verifiers that cached the per-tenant configuration.


Tenant Reference Extension

Receipts MAY include the org.peacprotocol/tenant_ref extension to carry explicit tenant metadata:

{
  "ext": [
    {
      "key": "org.peacprotocol/tenant_ref",
      "value": {
        "tenant_id": "tenant-abc",
        "environment": "production"
      }
    }
  ]
}

This extension is informational: it helps downstream systems route and filter receipts by tenant. It does NOT replace cryptographic isolation (Tier 2/3 key separation provides the actual isolation boundary).


Decision Matrix

Factor Tier 1 (Shared) Tier 2 (Scoped) Tier 3 (Isolated)
Setup complexity Low Medium High
Key compromise blast radius All tenants One tenant One tenant
Cross-tenant correlation risk High Medium Low
JWKS document size Small (1 key) Grows with tenants Small (1 key each)
Verifier configuration One issuer One issuer, many kids Many issuers
Key rotation independence None Per-tenant Per-tenant
Regulatory suitability Low Medium High
Max recommended tenants Unlimited ~20 (JWKS key limit) Unlimited

References