{
  "version": "certarail.production-iam-design.v1",
  "title": "CertaRail production IAM and authorization design",
  "status": "REQUIRES_ACTIVATION",
  "productionReady": false,
  "authority": "TARGET_PRODUCTION_DESIGN",
  "currentBoundary": "Current CertaRail runtime resolves digest-only Local bearer credentials to server-derived tenant, principal, organization and roles. It does not implement an OIDC/FAPI identity provider adapter, SCIM lifecycle, SPIFFE/STS workload issuance, complete PDP coverage, privileged JIT access or access-review workflow. Production startup remains blocked.",
  "sourceContract": "Existing runtime authentication remains owned by internal/bearerauth, internal/tenantauth and the current bearerAuth OpenAPI scheme. This target contract must not be represented as an implemented security scheme until the runtime adapter and operation-to-scope acceptance suite pass.",
  "references": [
    {
      "label": "OpenID FAPI 2.0 Security Profile Final",
      "href": "https://openid.net/specs/fapi-security-profile-2_0-final.html"
    },
    {
      "label": "OAuth 2.0 Security Best Current Practice · RFC 9700",
      "href": "https://www.rfc-editor.org/rfc/rfc9700.html"
    },
    {
      "label": "OAuth 2.0 Pushed Authorization Requests · RFC 9126",
      "href": "https://www.rfc-editor.org/rfc/rfc9126.html"
    },
    {
      "label": "OAuth 2.0 Mutual TLS · RFC 8705",
      "href": "https://www.rfc-editor.org/rfc/rfc8705.html"
    },
    {
      "label": "OAuth 2.0 DPoP · RFC 9449",
      "href": "https://www.rfc-editor.org/rfc/rfc9449.html"
    },
    {
      "label": "JWT client authentication · RFC 7523",
      "href": "https://www.rfc-editor.org/rfc/rfc7523.html"
    },
    {
      "label": "OAuth 2.0 Token Exchange · RFC 8693",
      "href": "https://www.rfc-editor.org/rfc/rfc8693.html"
    },
    {
      "label": "OpenID Connect Core 1.0",
      "href": "https://openid.net/specs/openid-connect-core-1_0-final.html"
    },
    {
      "label": "SCIM Protocol · RFC 7644",
      "href": "https://www.rfc-editor.org/rfc/rfc7644.html"
    },
    {
      "label": "SPIFFE Workload API",
      "href": "https://spiffe.io/docs/latest/spiffe-specs/spiffe_workload_api/"
    },
    {
      "label": "NIST SP 800-63B-4 Authentication Assurance Levels",
      "href": "https://pages.nist.gov/800-63-4/sp800-63b/aal/"
    }
  ],
  "decisions": {
    "identityProviders": [
      {
        "id": "tenant-workforce",
        "authority": "TENANT_MANAGED_ENTERPRISE_IDP_AND_AUTHORIZATION_SERVER",
        "subjects": "Customer workforce humans",
        "protocol": "OIDC/FAPI authorization server plus SCIM 2.0 lifecycle",
        "trustPolicy": "Each exact issuer registration is approved for one tenant boundary; discovery, authorization, token, JWKS and SCIM endpoints are pinned from reviewed metadata and never selected by a request.",
        "localPasswords": "PROHIBITED",
        "owner": "Tenant IAM owner"
      },
      {
        "id": "certarail-workforce",
        "authority": "CERTARAIL_WORKFORCE_ENTERPRISE_IDP_AND_AUTHORIZATION_SERVER",
        "subjects": "CertaRail workforce humans",
        "protocol": "OIDC/FAPI authorization server plus SCIM 2.0 lifecycle",
        "trustPolicy": "A separate workforce issuer and realm cannot mint tenant-member authority; tenant support requires a distinct approved JIT grant.",
        "localPasswords": "PROHIBITED",
        "owner": "CertaRail IAM owner"
      },
      {
        "id": "workload-authority",
        "authority": "ENVIRONMENT_SCOPED_SPIFFE_COMPATIBLE_CA_AND_STS",
        "subjects": "Internal workloads and controlled automation",
        "protocol": "SPIFFE X.509-SVID, Workload API and bounded token exchange",
        "trustPolicy": "Every canonical environment has a separate trust domain. Workload attestation binds namespace, service account and immutable deployment identity before issuing short-lived material.",
        "localPasswords": "PROHIBITED",
        "owner": "Platform Security"
      },
      {
        "id": "emergency-realm",
        "authority": "DEDICATED_HARDWARE_BOUND_EMERGENCY_REALM",
        "subjects": "Named break-glass custodians only",
        "protocol": "Phishing-resistant cryptographic authentication",
        "trustPolicy": "The emergency realm is isolated from normal federation, has no daily-use membership, requires two custodians to activate a 15-minute session, and pages Security immediately.",
        "localPasswords": "PROHIBITED",
        "owner": "CISO delegate plus independent custodian"
      }
    ],
    "humanIdentities": [
      {
        "id": "tenant-human",
        "source": "tenant-workforce",
        "tokenIssuer": "tenant-workforce",
        "subjectKey": "issuer + immutable sub",
        "lifecycle": "SCIM joiner-mover-leaver; disable and material role removal invalidate active entitlement within five minutes.",
        "authentication": "Phishing-resistant MFA is mandatory for Production; privileged actions require a fresh step-up no older than five minutes.",
        "authorization": "Tenant membership, roles and resource attributes come from the CertaRail entitlement directory, not mutable email, display name, groups in request payload, or a caller-supplied tenant_id."
      },
      {
        "id": "certarail-operator",
        "source": "certarail-workforce",
        "tokenIssuer": "certarail-workforce",
        "subjectKey": "issuer + immutable sub",
        "lifecycle": "SCIM lifecycle with named manager and system owner; support access is absent until a tenant-scoped JIT grant is approved.",
        "authentication": "Phishing-resistant MFA is mandatory; privileged access uses a managed device and fresh step-up.",
        "authorization": "Platform roles never imply tenant business authority. Tenant data access is read-only by default, ticket-bound, time-limited and separately audited."
      },
      {
        "id": "external-auditor",
        "source": "tenant-workforce",
        "tokenIssuer": "tenant-workforce",
        "subjectKey": "issuer + immutable sub + reviewed tenant membership",
        "lifecycle": "Time-bounded invitation with explicit sponsor, expiry and quarterly recertification while active.",
        "authentication": "Phishing-resistant MFA is mandatory.",
        "authorization": "Read-only evidence scopes and approved export boundaries; no command, approval, credential or role-management permissions."
      },
      {
        "id": "break-glass-custodian",
        "source": "emergency-realm",
        "tokenIssuer": "emergency-realm",
        "subjectKey": "emergency issuer + immutable sub + hardware key identity",
        "lifecycle": "Two sealed named identities, quarterly exercise, immediate credential replacement after every use or suspected compromise.",
        "authentication": "Two distinct custodians, non-exportable hardware authenticators and explicit authentication intent.",
        "authorization": "A 15-minute incident-scoped grant with command allowlist, session recording and mandatory next-business-day review; no standing tenant membership."
      }
    ],
    "serviceIdentities": [
      {
        "id": "internal-workload",
        "source": "workload-authority",
        "tokenIssuer": "workload-authority",
        "identity": "spiffe://<environment-trust-domain>/ns/<namespace>/sa/<service-account>",
        "authentication": "Attested X.509-SVID over mTLS",
        "credential": "Non-exported workload key and certificate valid for at most 60 minutes, streamed and rotated through the Workload API.",
        "authorization": "One service, deployment identity, environment and capability scope; no shared namespace credential or tenant wildcard."
      },
      {
        "id": "partner-service",
        "source": "tenant-workforce",
        "tokenIssuer": "tenant-workforce",
        "identity": "One confidential OAuth client per tenant, environment and system",
        "authentication": "private_key_jwt plus mTLS client authentication",
        "credential": "Hardware- or KMS-backed asymmetric key; five-minute certificate-bound access token and no refresh token.",
        "authorization": "Registration ceiling intersected with requested scopes and resource policy; a client cannot impersonate a human or switch tenant."
      },
      {
        "id": "release-automation",
        "source": "workload-authority",
        "tokenIssuer": "workload-authority",
        "identity": "Attested CI/release workload for one repository and environment",
        "authentication": "SPIFFE identity or approved CI OIDC token exchange",
        "credential": "Single-job token with exact audience and protected-environment binding; no stored cloud or cluster credential.",
        "authorization": "Promotion and activation scopes are separate, JIT and maker-checker controlled; application runtime identity cannot deploy itself."
      },
      {
        "id": "scim-provisioner",
        "source": "tenant-workforce",
        "tokenIssuer": "tenant-workforce",
        "identity": "One SCIM client per tenant issuer registration",
        "authentication": "mTLS-bound client credential",
        "credential": "Five-minute access token; asymmetric client key rotated under tenant IAM policy.",
        "authorization": "SCIM Users/Groups for its own tenant only; no Control Plane API scopes and no cross-tenant bulk operation."
      }
    ],
    "oauthOidcFlows": [
      {
        "id": "tenant-human-web",
        "actors": "Tenant human browser through the tenant-facing CertaRail BFF",
        "grant": "authorization_code",
        "tokenIssuer": "tenant-workforce",
        "clientAuthentication": "private_key_jwt or MTLS at the BFF",
        "senderConstraint": "MTLS",
        "subjectCredential": "OIDC_ID_TOKEN",
        "controls": [
          "FAPI 2.0 Security Profile",
          "PKCE S256",
          "PAR",
          "exact redirect URI",
          "state + nonce + iss validation",
          "BFF keeps access and refresh tokens out of browser JavaScript"
        ]
      },
      {
        "id": "operator-web",
        "actors": "CertaRail operator browser through the operations BFF",
        "grant": "authorization_code",
        "tokenIssuer": "certarail-workforce",
        "clientAuthentication": "private_key_jwt or MTLS at the BFF",
        "senderConstraint": "MTLS",
        "subjectCredential": "OIDC_ID_TOKEN",
        "controls": [
          "FAPI 2.0 Security Profile",
          "PKCE S256",
          "PAR",
          "separate issuer, client, audience and route plane",
          "no tenant business role from upstream groups",
          "support access requires a current tenant-scoped JIT grant"
        ]
      },
      {
        "id": "partner-service",
        "actors": "Tenant or partner backend",
        "grant": "client_credentials",
        "tokenIssuer": "tenant-workforce",
        "clientAuthentication": "private_key_jwt plus MTLS",
        "senderConstraint": "MTLS",
        "subjectCredential": "REGISTERED_CLIENT_KEY",
        "controls": [
          "exact issuer and audience",
          "certificate-bound access token",
          "no refresh token",
          "one client per tenant and environment",
          "asymmetric key in HSM or KMS"
        ]
      },
      {
        "id": "internal-workload",
        "actors": "Attested CertaRail workload",
        "grant": "token_exchange",
        "tokenIssuer": "workload-authority",
        "clientAuthentication": "MTLS workload channel",
        "senderConstraint": "MTLS",
        "subjectCredential": "SPIFFE_X509_SVID",
        "controls": [
          "RFC 8693 token exchange",
          "exact requested audience",
          "no unrestricted impersonation",
          "actor chain retained in audit",
          "environment trust domains never federate by default"
        ]
      },
      {
        "id": "delegated-background-job",
        "actors": "Queued job acting for a previously authorized principal",
        "grant": "token_exchange",
        "tokenIssuer": "workload-authority",
        "clientAuthentication": "Attested workload MTLS",
        "senderConstraint": "MTLS",
        "subjectCredential": "OPAQUE_DELEGATION_GRANT",
        "controls": [
          "immutable actor and subject chain",
          "scope can only narrow",
          "resource and command binding",
          "single purpose and expiry",
          "revocation checked before execution"
        ]
      }
    ],
    "prohibitedFlows": [
      "implicit",
      "hybrid",
      "password",
      "authorization_code_without_pkce",
      "shared_client_secret",
      "unrestricted_token_exchange",
      "device_authorization_at_launch"
    ],
    "credentialPolicy": {
      "authorizationCodeSeconds": 60,
      "parRequestUriSeconds": 60,
      "accessTokenSeconds": 300,
      "serviceAccessTokenSeconds": 300,
      "privilegedAccessTokenSeconds": 180,
      "refreshTokenAbsoluteSeconds": 28800,
      "refreshTokenRotation": "ONE_TIME_FAMILY_REVOKE_ON_REUSE",
      "browserSessionIdleSeconds": 1800,
      "browserSessionAbsoluteSeconds": 28800,
      "privilegedSessionSeconds": 900,
      "x509SvidSeconds": 3600,
      "maxClockSkewSeconds": 60,
      "signingKeyPolicy": "Asymmetric keys are HSM/KMS backed, have named owners and rotate on an approved schedule with tested current/next overlap; private material never enters source, image, environment dump, URL, log or evidence payload.",
      "validation": "Validate exact issuer, audience, authorized party/client, signature algorithm and key ID, expiry, not-before, issued-at, sender constraint, token ID, entitlement version and environment. Unknown issuer/key/scope or stale authorization fails closed.",
      "revocation": "Human disable, service disable, key compromise and privileged-grant withdrawal reach the PDP immediately and every resource server within five minutes; privileged operations always consult live entitlement state."
    },
    "scopes": [
      {
        "id": "identity:profile:read",
        "family": "identity",
        "effect": "READ",
        "privileged": false,
        "description": "Read the authenticated principal and effective tenant context."
      },
      {
        "id": "eligibility:read",
        "family": "eligibility",
        "effect": "READ",
        "privileged": false,
        "description": "Read eligibility decisions and safe evidence."
      },
      {
        "id": "eligibility:evaluate",
        "family": "eligibility",
        "effect": "WRITE",
        "privileged": false,
        "description": "Submit an eligibility evaluation within tenant policy."
      },
      {
        "id": "eligibility:review",
        "family": "eligibility",
        "effect": "APPROVE",
        "privileged": true,
        "description": "Review controlled eligibility exceptions; never executes value movement."
      },
      {
        "id": "checkout:read",
        "family": "checkout",
        "effect": "READ",
        "privileged": false,
        "description": "Read tenant-scoped checkout state and evidence."
      },
      {
        "id": "checkout:write",
        "family": "checkout",
        "effect": "WRITE",
        "privileged": false,
        "description": "Create or advance an authorized checkout command."
      },
      {
        "id": "deal:read",
        "family": "deal",
        "effect": "READ",
        "privileged": false,
        "description": "Read a permitted deal and its evidence."
      },
      {
        "id": "deal:write",
        "family": "deal",
        "effect": "WRITE",
        "privileged": false,
        "description": "Prepare or amend a deal under mandate and resource policy."
      },
      {
        "id": "deal:approve",
        "family": "deal",
        "effect": "APPROVE",
        "privileged": true,
        "description": "Approve a deal prepared by a different principal."
      },
      {
        "id": "onboarding:read",
        "family": "onboarding",
        "effect": "READ",
        "privileged": false,
        "description": "Read organization onboarding state."
      },
      {
        "id": "onboarding:write",
        "family": "onboarding",
        "effect": "WRITE",
        "privileged": false,
        "description": "Create and edit a draft before review."
      },
      {
        "id": "onboarding:review",
        "family": "onboarding",
        "effect": "APPROVE",
        "privileged": true,
        "description": "Review a submitted draft as an independent principal."
      },
      {
        "id": "provider:read",
        "family": "provider",
        "effect": "READ",
        "privileged": false,
        "description": "Read approved provider connection metadata and observations."
      },
      {
        "id": "provider:operate",
        "family": "provider",
        "effect": "WRITE",
        "privileged": true,
        "description": "Prepare provider commands within exact connection and mandate scope."
      },
      {
        "id": "provider:approve",
        "family": "provider",
        "effect": "APPROVE",
        "privileged": true,
        "description": "Approve provider operation or credential binding as checker."
      },
      {
        "id": "webhook:read",
        "family": "webhook",
        "effect": "READ",
        "privileged": false,
        "description": "Read endpoint and delivery evidence without secret material."
      },
      {
        "id": "webhook:manage",
        "family": "webhook",
        "effect": "WRITE",
        "privileged": true,
        "description": "Create, verify, pause, rotate, revoke or delete an endpoint."
      },
      {
        "id": "webhook:replay",
        "family": "webhook",
        "effect": "RECOVERY",
        "privileged": true,
        "description": "Request a bounded, approved replay without changing event identity."
      },
      {
        "id": "evidence:read",
        "family": "evidence",
        "effect": "READ",
        "privileged": false,
        "description": "Read approved evidence projections for accessible resources."
      },
      {
        "id": "audit:export",
        "family": "audit",
        "effect": "EXPORT",
        "privileged": true,
        "description": "Export a bounded audit set under data-classification policy."
      },
      {
        "id": "reporting:read",
        "family": "reporting",
        "effect": "READ",
        "privileged": false,
        "description": "Read report drafts and receipt evidence."
      },
      {
        "id": "reporting:prepare",
        "family": "reporting",
        "effect": "WRITE",
        "privileged": true,
        "description": "Prepare a report draft; official submission is a separate activation."
      },
      {
        "id": "iam:read",
        "family": "iam",
        "effect": "READ",
        "privileged": true,
        "description": "Read memberships, grants, clients and access-review evidence."
      },
      {
        "id": "iam:manage",
        "family": "iam",
        "effect": "WRITE",
        "privileged": true,
        "description": "Propose membership, role, issuer or client changes."
      },
      {
        "id": "iam:review",
        "family": "iam",
        "effect": "APPROVE",
        "privileged": true,
        "description": "Independently approve IAM changes and access reviews."
      },
      {
        "id": "runtime:read",
        "family": "runtime",
        "effect": "READ",
        "privileged": true,
        "description": "Read safe platform health and configuration evidence."
      },
      {
        "id": "runtime:operate",
        "family": "runtime",
        "effect": "RECOVERY",
        "privileged": true,
        "description": "Perform approved bounded maintenance or recovery."
      },
      {
        "id": "security:respond",
        "family": "security",
        "effect": "RECOVERY",
        "privileged": true,
        "description": "Revoke, contain and investigate under an incident ticket."
      },
      {
        "id": "support:inspect",
        "family": "support",
        "effect": "READ",
        "privileged": true,
        "description": "JIT read-only inspection of one approved tenant and case."
      },
      {
        "id": "production:activate",
        "family": "production",
        "effect": "ACTIVATE",
        "privileged": true,
        "description": "Approve an evidence-bound capability activation; not a runtime wildcard."
      }
    ],
    "roles": [
      {
        "id": "corporate:maker",
        "principalKinds": [
          "HUMAN"
        ],
        "grants": [
          "identity:profile:read",
          "eligibility:read",
          "eligibility:evaluate",
          "checkout:read",
          "checkout:write",
          "deal:read",
          "deal:write",
          "provider:read",
          "provider:operate",
          "evidence:read"
        ],
        "constraints": "Mandate, amount, connection and resource ownership; cannot approve own command."
      },
      {
        "id": "corporate:approver",
        "principalKinds": [
          "HUMAN"
        ],
        "grants": [
          "identity:profile:read",
          "eligibility:read",
          "checkout:read",
          "deal:read",
          "deal:approve",
          "provider:read",
          "provider:approve",
          "evidence:read"
        ],
        "constraints": "Independent checker; cannot prepare the command being approved."
      },
      {
        "id": "corporate:compliance",
        "principalKinds": [
          "HUMAN"
        ],
        "grants": [
          "identity:profile:read",
          "eligibility:read",
          "eligibility:review",
          "deal:read",
          "onboarding:read",
          "onboarding:review",
          "evidence:read",
          "reporting:read"
        ],
        "constraints": "Review authority only; no deal preparation or provider execution scope."
      },
      {
        "id": "corporate:auditor",
        "principalKinds": [
          "HUMAN"
        ],
        "grants": [
          "identity:profile:read",
          "eligibility:read",
          "checkout:read",
          "deal:read",
          "onboarding:read",
          "provider:read",
          "webhook:read",
          "evidence:read",
          "reporting:read",
          "iam:read",
          "audit:export"
        ],
        "constraints": "Read-only; export requires a separately approved bounded operation."
      },
      {
        "id": "corporate:admin",
        "principalKinds": [
          "HUMAN"
        ],
        "grants": [
          "identity:profile:read",
          "iam:read",
          "iam:manage"
        ],
        "constraints": "May propose tenant membership and roles; cannot approve own grant or perform business commands."
      },
      {
        "id": "onboarding:owner",
        "principalKinds": [
          "HUMAN"
        ],
        "grants": [
          "identity:profile:read",
          "onboarding:read",
          "onboarding:write"
        ],
        "constraints": "Own organization draft only; no review of own submission."
      },
      {
        "id": "onboarding:editor",
        "principalKinds": [
          "HUMAN"
        ],
        "grants": [
          "identity:profile:read",
          "onboarding:read",
          "onboarding:write"
        ],
        "constraints": "Assigned organization draft only; no review scope."
      },
      {
        "id": "onboarding:reviewer",
        "principalKinds": [
          "HUMAN"
        ],
        "grants": [
          "identity:profile:read",
          "onboarding:read",
          "onboarding:review"
        ],
        "constraints": "Independent reviewer; creator/updater cannot review the same version."
      },
      {
        "id": "developer:admin",
        "principalKinds": [
          "HUMAN"
        ],
        "grants": [
          "identity:profile:read",
          "webhook:read",
          "webhook:manage",
          "webhook:replay",
          "evidence:read"
        ],
        "constraints": "Exact tenant and environment; production secret/replay changes remain privileged operations."
      },
      {
        "id": "submission:operator",
        "principalKinds": [
          "HUMAN",
          "SERVICE"
        ],
        "grants": [
          "identity:profile:read",
          "reporting:read",
          "reporting:prepare",
          "evidence:read"
        ],
        "constraints": "Draft preparation only unless an independently activated official transport scope exists."
      },
      {
        "id": "retail:buyer",
        "principalKinds": [
          "HUMAN"
        ],
        "grants": [
          "identity:profile:read",
          "checkout:read",
          "checkout:write",
          "deal:read",
          "deal:write"
        ],
        "constraints": "Own subject and admission grant only; no privileged read or approval."
      },
      {
        "id": "deal:reader",
        "principalKinds": [
          "HUMAN",
          "SERVICE"
        ],
        "grants": [
          "identity:profile:read",
          "deal:read",
          "evidence:read"
        ],
        "constraints": "Explicit resource assignment; no tenant-wide inference from the role name."
      },
      {
        "id": "platform:operator",
        "principalKinds": [
          "HUMAN"
        ],
        "grants": [
          "identity:profile:read",
          "runtime:read",
          "runtime:operate",
          "evidence:read"
        ],
        "constraints": "No tenant data by default; maintenance is JIT and ticket-bound."
      },
      {
        "id": "security:operator",
        "principalKinds": [
          "HUMAN"
        ],
        "grants": [
          "identity:profile:read",
          "iam:read",
          "iam:review",
          "security:respond",
          "audit:export"
        ],
        "constraints": "Incident and IAM checker duties; cannot silently assume tenant business roles."
      },
      {
        "id": "support:readonly",
        "principalKinds": [
          "HUMAN"
        ],
        "grants": [
          "identity:profile:read",
          "support:inspect",
          "evidence:read"
        ],
        "constraints": "One tenant, one ticket and at most 60 minutes; safe projections only."
      },
      {
        "id": "release:operator",
        "principalKinds": [
          "HUMAN",
          "SERVICE"
        ],
        "grants": [
          "identity:profile:read",
          "runtime:read",
          "production:activate"
        ],
        "constraints": "Protected environment and release digest binding; cannot approve own activation."
      },
      {
        "id": "audit:reviewer",
        "principalKinds": [
          "HUMAN"
        ],
        "grants": [
          "identity:profile:read",
          "iam:read",
          "iam:review",
          "evidence:read",
          "audit:export"
        ],
        "constraints": "Independent review and export approval; no mutable business scope."
      }
    ],
    "authorizationDecision": "INTERSECTION_CLIENT_SCOPE_ROLE_RESOURCE_POLICY",
    "defaultDecision": "DENY",
    "tenantIsolation": [
      {
        "layer": "FEDERATION_REGISTRY",
        "requirement": "An exact issuer and client registration maps to one tenant and canonical environment. Dynamic issuer, JWKS URI, redirect URI and tenant selection are prohibited.",
        "negativeEvidence": "Unknown issuer, issuer reused for an unapproved tenant, metadata redirect, JWKS host change and cross-environment client are rejected."
      },
      {
        "layer": "TOKEN_VALIDATION",
        "requirement": "Resource servers validate issuer, audience, client/authorized party, time, signature algorithm, key, sender constraint and entitlement version before resolving membership.",
        "negativeEvidence": "Wrong audience, expired/future token, algorithm downgrade, unknown key, replayed proof and stale entitlement version are rejected."
      },
      {
        "layer": "HTTP_CONTEXT",
        "requirement": "Authentication middleware creates one immutable identity context. Tenant, organization, principal, environment and roles are server-derived; conflicting body/header/query assertions fail closed.",
        "negativeEvidence": "Caller-supplied tenant_id, duplicate Authorization, mixed checkout/operator credentials and conflicting organization are rejected without existence disclosure."
      },
      {
        "layer": "POLICY_DECISION_POINT",
        "requirement": "Authorization is the intersection of registered client ceiling, token scopes, current role grants and resource attributes including tenant, organization, environment, mandate, owner and maker-checker history.",
        "negativeEvidence": "Scope-only, role-only, stale-cache, self-approval, resource-owner mismatch and environment escalation are denied."
      },
      {
        "layer": "POSTGRESQL_RLS",
        "requirement": "Every tenant relation uses composite tenant keys, transaction-local tenant context and FORCE RLS. Runtime roles are not owners and have no superuser, BYPASSRLS, DDL or inherited elevated membership.",
        "negativeEvidence": "Cross-tenant read/write, unset tenant context, direct table mutation, owner/BYPASSRLS startup and connection-pool context leakage are denied."
      },
      {
        "layer": "ASYNC_AND_CACHE",
        "requirement": "Queue, inbox, outbox, cache, idempotency and object-storage identities include the authoritative tenant/environment boundary; workers re-authorize before external or privileged effects.",
        "negativeEvidence": "Cross-tenant cache keys, foreign queue records, reused idempotency keys, stale delegated grants and object references from another tenant are quarantined or denied."
      },
      {
        "layer": "SUPPORT_ACCESS",
        "requirement": "Internal support has no implicit tenant membership. Access names one tenant, case, purpose, safe data projection, approver and expiry and is visible to the tenant audit trail.",
        "negativeEvidence": "Standing global support, hidden impersonation, multi-tenant query, expired JIT grant and access without ticket/approval are denied and alerted."
      }
    ],
    "privilegedOperations": [
      {
        "id": "IDP_TRUST_CHANGE",
        "action": "Add, change, disable or rotate issuer, metadata, redirect URI, JWKS or SCIM trust.",
        "requiredScopes": [
          "iam:manage",
          "iam:review"
        ],
        "approval": "TWO_DISTINCT_PRINCIPALS",
        "selfApproval": "PROHIBITED",
        "maxElevationMinutes": 30,
        "stepUpMaxAgeMinutes": 5,
        "evidence": [
          "ticket",
          "before/after digest",
          "maker and checker",
          "conformance plus rollback result"
        ]
      },
      {
        "id": "PRIVILEGED_ROLE_GRANT",
        "action": "Grant, extend or remove a privileged human role or JIT eligibility.",
        "requiredScopes": [
          "iam:manage",
          "iam:review"
        ],
        "approval": "TWO_DISTINCT_PRINCIPALS",
        "selfApproval": "PROHIBITED",
        "maxElevationMinutes": 60,
        "stepUpMaxAgeMinutes": 5,
        "evidence": [
          "ticket and business reason",
          "subject and role",
          "maker and checker",
          "expiry and revocation observation"
        ]
      },
      {
        "id": "SERVICE_IDENTITY_CHANGE",
        "action": "Create, rescope, rotate, disable or delete a service identity.",
        "requiredScopes": [
          "iam:manage",
          "iam:review"
        ],
        "approval": "TWO_DISTINCT_PRINCIPALS",
        "selfApproval": "PROHIBITED",
        "maxElevationMinutes": 60,
        "stepUpMaxAgeMinutes": 5,
        "evidence": [
          "owner",
          "client/workload identity",
          "scope and audience diff",
          "rotation or disable proof"
        ]
      },
      {
        "id": "PRODUCTION_ACTIVATION",
        "action": "Activate a capability or external-effect route in Production.",
        "requiredScopes": [
          "production:activate",
          "iam:review"
        ],
        "approval": "TWO_DISTINCT_PRINCIPALS",
        "selfApproval": "PROHIBITED",
        "maxElevationMinutes": 30,
        "stepUpMaxAgeMinutes": 5,
        "evidence": [
          "release digest",
          "closed activation gates",
          "maker and checker",
          "rollback and post-change observation"
        ]
      },
      {
        "id": "PROVIDER_CREDENTIAL_BINDING",
        "action": "Bind, rotate, revoke or reassign a production provider credential or account.",
        "requiredScopes": [
          "provider:approve",
          "security:respond"
        ],
        "approval": "TWO_DISTINCT_PRINCIPALS",
        "selfApproval": "PROHIBITED",
        "maxElevationMinutes": 30,
        "stepUpMaxAgeMinutes": 5,
        "evidence": [
          "provider/account reference digest",
          "vault version",
          "maker and checker",
          "negative old-key test"
        ]
      },
      {
        "id": "MANUAL_REPLAY_OR_REQUEUE",
        "action": "Replay a delivery/event or requeue a dead-lettered operation.",
        "requiredScopes": [
          "webhook:replay",
          "runtime:operate"
        ],
        "approval": "TWO_DISTINCT_PRINCIPALS",
        "selfApproval": "PROHIBITED",
        "maxElevationMinutes": 30,
        "stepUpMaxAgeMinutes": 5,
        "evidence": [
          "incident/change ticket",
          "immutable source digest/range",
          "maker and checker",
          "bounded outcome and reconciliation"
        ]
      },
      {
        "id": "TENANT_DATA_EXPORT",
        "action": "Export restricted tenant evidence or audit data.",
        "requiredScopes": [
          "audit:export",
          "iam:review"
        ],
        "approval": "TWO_DISTINCT_PRINCIPALS",
        "selfApproval": "PROHIBITED",
        "maxElevationMinutes": 30,
        "stepUpMaxAgeMinutes": 5,
        "evidence": [
          "purpose and legal basis reference",
          "tenant/data/time range",
          "maker and checker",
          "encrypted artifact expiry and access log"
        ]
      },
      {
        "id": "AUDIT_OR_RETENTION_POLICY_CHANGE",
        "action": "Change audit destination, retention, legal hold or evidence integrity policy.",
        "requiredScopes": [
          "iam:review",
          "audit:export"
        ],
        "approval": "TWO_DISTINCT_PRINCIPALS",
        "selfApproval": "PROHIBITED",
        "maxElevationMinutes": 30,
        "stepUpMaxAgeMinutes": 5,
        "evidence": [
          "policy diff",
          "owner approvals",
          "maker and checker",
          "validation and rollback result"
        ]
      },
      {
        "id": "BREAK_GLASS_SESSION",
        "action": "Open emergency access when the normal control plane is unavailable.",
        "requiredScopes": [
          "security:respond",
          "runtime:operate"
        ],
        "approval": "TWO_DISTINCT_PRINCIPALS",
        "selfApproval": "PROHIBITED",
        "maxElevationMinutes": 15,
        "stepUpMaxAgeMinutes": 5,
        "evidence": [
          "declared incident",
          "two hardware-bound custodians",
          "complete command/session record",
          "credential replacement and next-day review"
        ]
      }
    ],
    "accessReviews": [
      {
        "id": "event-driven-jml",
        "cadence": "CONTINUOUS; leaver and critical role removal SLA <= 5 minutes",
        "scope": "Human memberships, group mappings, active sessions and JIT grants",
        "reviewer": "Tenant or CertaRail IAM owner matching the identity authority",
        "evidence": [
          "SCIM event ID",
          "before/after entitlement digest",
          "session revocation result",
          "completion timestamp and SLA"
        ]
      },
      {
        "id": "monthly-privileged-and-service",
        "cadence": "MONTHLY",
        "scope": "Privileged-role eligibility, service clients, workload identities, keys/certificates, owners and last use",
        "reviewer": "Security owner plus independent system owner",
        "evidence": [
          "immutable population snapshot",
          "owner attestations",
          "unused/orphaned findings",
          "revocations, exceptions and due dates"
        ]
      },
      {
        "id": "quarterly-all-human-access",
        "cadence": "QUARTERLY",
        "scope": "Every human tenant membership, role, scope ceiling, resource assignment and separation-of-duties conflict",
        "reviewer": "Tenant access owner; privileged reviewers cannot certify themselves",
        "evidence": [
          "snapshot digest and as-of time",
          "reviewer identities",
          "decision per principal",
          "completed removals and tracked exceptions"
        ]
      },
      {
        "id": "semiannual-federation-trust",
        "cadence": "SEMIANNUAL AND BEFORE MATERIAL FEDERATION CHANGE",
        "scope": "Issuers, metadata, redirect URIs, JWKS/certificates, SCIM clients, OAuth clients, audiences and trust domains",
        "reviewer": "IAM architect plus Security checker",
        "evidence": [
          "registered trust inventory",
          "metadata/key fingerprints",
          "conformance and negative-test report",
          "approved changes and rollback evidence"
        ]
      },
      {
        "id": "post-incident-review",
        "cadence": "WITHIN 1 BUSINESS DAY AFTER BREAK-GLASS; WITHIN 5 BUSINESS DAYS AFTER OTHER IAM INCIDENTS",
        "scope": "Incident grants, authentication events, token/client use, commands, exports and containment",
        "reviewer": "Incident commander plus independent Security/Audit reviewer",
        "evidence": [
          "incident timeline",
          "principal/token/session correlation",
          "commands and accessed scope",
          "revocation, credential replacement and actions"
        ]
      }
    ],
    "activationGates": [
      {
        "id": "IAM_IDP_SELECTED_AND_CONFORMANT",
        "owner": "IAM Architecture",
        "status": "OPEN",
        "evidence": "Named products/deployments, FAPI 2.0/OIDC conformance result, exact issuer metadata and ownership."
      },
      {
        "id": "IAM_RUNTIME_ADAPTER_IMPLEMENTED",
        "owner": "Application Security",
        "status": "OPEN",
        "evidence": "OIDC/JWKS, mTLS/DPoP, token exchange and SCIM adapters with negative tests; OpenAPI updated only after runtime acceptance."
      },
      {
        "id": "IAM_PDP_POLICY_ENFORCED",
        "owner": "Application Security",
        "status": "OPEN",
        "evidence": "Operation-to-scope registry, RBAC/ABAC decisions, live revocation and self-approval denial tests."
      },
      {
        "id": "IAM_TENANT_ISOLATION_PROVEN",
        "owner": "Security Engineering",
        "status": "OPEN",
        "evidence": "HTTP, cache/queue and PostgreSQL FORCE RLS cross-tenant suite using non-owner/non-BYPASSRLS runtime roles."
      },
      {
        "id": "IAM_PRIVILEGED_ACCESS_EXERCISED",
        "owner": "Security Operations",
        "status": "OPEN",
        "evidence": "JIT, step-up, maker-checker, expiry, emergency access and audit drill with denied bypass attempts."
      },
      {
        "id": "IAM_ACCESS_REVIEW_COMPLETED",
        "owner": "IAM Governance",
        "status": "OPEN",
        "evidence": "One complete monthly and quarterly review cycle with removals, exceptions, SLA and immutable evidence."
      },
      {
        "id": "IAM_SECURITY_ACCEPTANCE_COMPLETE",
        "owner": "CISO delegate",
        "status": "OPEN",
        "evidence": "Threat-model update, external penetration test, incident/revocation drill, residual-risk acceptance and production activation record."
      }
    ]
  },
  "sections": [
    {
      "id": "production-current-boundary",
      "title": "Текущая граница реализации",
      "lead": "A22.1 фиксирует target contract, но не включает Production identity runtime. Действующий API по-прежнему использует digest-only Local bearer и server-derived tenant/principal/organization/roles; production startup остаётся заблокированным.",
      "table": {
        "caption": "Design versus runtime evidence",
        "columns": [
          "Контур",
          "Текущий факт",
          "Статус A22.1"
        ],
        "rows": [
          [
            "Local bearer resolver",
            "Реализован: digest-only static/hosted credential resolution",
            "Не является Production IdP"
          ],
          [
            "Tenant/role context",
            "Реализован для отдельных HTTP/domain seams и FORCE RLS relations",
            "Не доказывает полный operation-to-policy coverage"
          ],
          [
            "OIDC/FAPI/SCIM",
            "Runtime adapter отсутствует",
            "Target design defined · activation open"
          ],
          [
            "Workload identity/STS",
            "Production SPIFFE/STS integration отсутствует",
            "Target design defined · activation open"
          ],
          [
            "JIT/access reviews",
            "Некоторые maker-checker guards существуют локально",
            "Production lifecycle and evidence not activated"
          ]
        ]
      },
      "callout": {
        "tone": "critical",
        "title": "DESIGN ONLY · Production access остаётся закрытым",
        "description": "Ни этот документ, ни generated JSON не выдают credential, не подключают IdP, не меняют OpenAPI security scheme и не разрешают production startup. Все activation gates остаются OPEN."
      }
    },
    {
      "id": "production-idp",
      "title": "IdP и trust topology",
      "lead": "CertaRail не становится IdP, password authority или universal token issuer. Customer-managed enterprise IdP/authorization server подтверждает tenant humans и partner clients; отдельный workforce authority — CertaRail operators; environment-scoped SPIFFE CA/STS — workloads; isolated emergency realm — только break-glass.",
      "table": {
        "caption": "Authoritative identity providers",
        "columns": [
          "Profile",
          "Authority",
          "Subjects",
          "Trust rule",
          "Owner"
        ],
        "rows": [
          [
            "tenant-workforce",
            "TENANT_MANAGED_ENTERPRISE_IDP_AND_AUTHORIZATION_SERVER",
            "Customer workforce humans",
            "Each exact issuer registration is approved for one tenant boundary; discovery, authorization, token, JWKS and SCIM endpoints are pinned from reviewed metadata and never selected by a request.",
            "Tenant IAM owner"
          ],
          [
            "certarail-workforce",
            "CERTARAIL_WORKFORCE_ENTERPRISE_IDP_AND_AUTHORIZATION_SERVER",
            "CertaRail workforce humans",
            "A separate workforce issuer and realm cannot mint tenant-member authority; tenant support requires a distinct approved JIT grant.",
            "CertaRail IAM owner"
          ],
          [
            "workload-authority",
            "ENVIRONMENT_SCOPED_SPIFFE_COMPATIBLE_CA_AND_STS",
            "Internal workloads and controlled automation",
            "Every canonical environment has a separate trust domain. Workload attestation binds namespace, service account and immutable deployment identity before issuing short-lived material.",
            "Platform Security"
          ],
          [
            "emergency-realm",
            "DEDICATED_HARDWARE_BOUND_EMERGENCY_REALM",
            "Named break-glass custodians only",
            "The emergency realm is isolated from normal federation, has no daily-use membership, requires two custodians to activate a 15-minute session, and pages Security immediately.",
            "CISO delegate plus independent custodian"
          ]
        ]
      },
      "bullets": [
        "Каждый issuer регистрируется exact HTTPS value и привязывается к одному tenant/environment boundary; request-time discovery и dynamic client registration запрещены.",
        "Каждый route plane принимает access token только от своего registered authority и только с exact CertaRail audience; ID token, assertion либо token другого plane не являются API credential.",
        "CertaRail verifier после cryptographic validation заново разрешает current membership, entitlement version и resource policy. Upstream groups/roles не становятся CertaRail authority напрямую.",
        "Metadata/JWKS rotation допускает reviewed current/next overlap, pinning разрешённых algorithms и bounded cache; неизвестный kid или stale metadata fail closed.",
        "Vendor выбирается на activation по этому conformance profile. Имя продукта не подменяет FAPI/OIDC, operational ownership, residency, HA, recovery и exit evidence."
      ]
    },
    {
      "id": "production-human-identities",
      "title": "Human identities",
      "table": {
        "caption": "Human identity classes",
        "columns": [
          "Class",
          "Authentication source",
          "API token issuer",
          "Authority key",
          "Lifecycle",
          "Authorization boundary"
        ],
        "rows": [
          [
            "tenant-human",
            "tenant-workforce",
            "tenant-workforce",
            "issuer + immutable sub",
            "SCIM joiner-mover-leaver; disable and material role removal invalidate active entitlement within five minutes.",
            "Tenant membership, roles and resource attributes come from the CertaRail entitlement directory, not mutable email, display name, groups in request payload, or a caller-supplied tenant_id."
          ],
          [
            "certarail-operator",
            "certarail-workforce",
            "certarail-workforce",
            "issuer + immutable sub",
            "SCIM lifecycle with named manager and system owner; support access is absent until a tenant-scoped JIT grant is approved.",
            "Platform roles never imply tenant business authority. Tenant data access is read-only by default, ticket-bound, time-limited and separately audited."
          ],
          [
            "external-auditor",
            "tenant-workforce",
            "tenant-workforce",
            "issuer + immutable sub + reviewed tenant membership",
            "Time-bounded invitation with explicit sponsor, expiry and quarterly recertification while active.",
            "Read-only evidence scopes and approved export boundaries; no command, approval, credential or role-management permissions."
          ],
          [
            "break-glass-custodian",
            "emergency-realm",
            "emergency-realm",
            "emergency issuer + immutable sub + hardware key identity",
            "Two sealed named identities, quarterly exercise, immediate credential replacement after every use or suspected compromise.",
            "A 15-minute incident-scoped grant with command allowlist, session recording and mandatory next-business-day review; no standing tenant membership."
          ]
        ]
      },
      "bullets": [
        "Shared, generic, orphaned и non-expiring human accounts запрещены; email, display name и mutable group label не являются identity key.",
        "Phishing-resistant MFA обязателен для Production humans; SMS/voice/manual OTP не являются единственным доступным privileged method.",
        "Browser получает только Secure, HttpOnly, host-only BFF session cookie; access/refresh tokens не попадают в JavaScript, URL, localStorage, analytics или support evidence."
      ]
    },
    {
      "id": "production-service-identities",
      "title": "Service identities",
      "table": {
        "caption": "Non-human identity classes",
        "columns": [
          "Class",
          "Attestation/registration authority",
          "Token issuer",
          "Identity",
          "Authentication",
          "Credential",
          "Authorization boundary"
        ],
        "rows": [
          [
            "internal-workload",
            "workload-authority",
            "workload-authority",
            "spiffe://<environment-trust-domain>/ns/<namespace>/sa/<service-account>",
            "Attested X.509-SVID over mTLS",
            "Non-exported workload key and certificate valid for at most 60 minutes, streamed and rotated through the Workload API.",
            "One service, deployment identity, environment and capability scope; no shared namespace credential or tenant wildcard."
          ],
          [
            "partner-service",
            "tenant-workforce",
            "tenant-workforce",
            "One confidential OAuth client per tenant, environment and system",
            "private_key_jwt plus mTLS client authentication",
            "Hardware- or KMS-backed asymmetric key; five-minute certificate-bound access token and no refresh token.",
            "Registration ceiling intersected with requested scopes and resource policy; a client cannot impersonate a human or switch tenant."
          ],
          [
            "release-automation",
            "workload-authority",
            "workload-authority",
            "Attested CI/release workload for one repository and environment",
            "SPIFFE identity or approved CI OIDC token exchange",
            "Single-job token with exact audience and protected-environment binding; no stored cloud or cluster credential.",
            "Promotion and activation scopes are separate, JIT and maker-checker controlled; application runtime identity cannot deploy itself."
          ],
          [
            "scim-provisioner",
            "tenant-workforce",
            "tenant-workforce",
            "One SCIM client per tenant issuer registration",
            "mTLS-bound client credential",
            "Five-minute access token; asymmetric client key rotated under tenant IAM policy.",
            "SCIM Users/Groups for its own tenant only; no Control Plane API scopes and no cross-tenant bulk operation."
          ]
        ]
      },
      "bullets": [
        "One workload/client identity cannot be shared across services, tenants or canonical environments.",
        "Human bearer, browser cookie and static client_secret are prohibited for service execution.",
        "Ownership, contact, environment, audiences, scopes, key/certificate expiry and last use are mandatory inventory fields."
      ]
    },
    {
      "id": "production-oauth-oidc",
      "title": "OAuth/OIDC flows",
      "table": {
        "caption": "Approved Production flows",
        "columns": [
          "Profile",
          "Actors",
          "Grant",
          "Token issuer",
          "Client authentication",
          "Sender constraint",
          "Required controls"
        ],
        "rows": [
          [
            "tenant-human-web",
            "Tenant human browser through the tenant-facing CertaRail BFF",
            "authorization_code",
            "tenant-workforce",
            "private_key_jwt or MTLS at the BFF",
            "MTLS",
            "FAPI 2.0 Security Profile; PKCE S256; PAR; exact redirect URI; state + nonce + iss validation; BFF keeps access and refresh tokens out of browser JavaScript"
          ],
          [
            "operator-web",
            "CertaRail operator browser through the operations BFF",
            "authorization_code",
            "certarail-workforce",
            "private_key_jwt or MTLS at the BFF",
            "MTLS",
            "FAPI 2.0 Security Profile; PKCE S256; PAR; separate issuer, client, audience and route plane; no tenant business role from upstream groups; support access requires a current tenant-scoped JIT grant"
          ],
          [
            "partner-service",
            "Tenant or partner backend",
            "client_credentials",
            "tenant-workforce",
            "private_key_jwt plus MTLS",
            "MTLS",
            "exact issuer and audience; certificate-bound access token; no refresh token; one client per tenant and environment; asymmetric key in HSM or KMS"
          ],
          [
            "internal-workload",
            "Attested CertaRail workload",
            "token_exchange",
            "workload-authority",
            "MTLS workload channel",
            "MTLS",
            "RFC 8693 token exchange; exact requested audience; no unrestricted impersonation; actor chain retained in audit; environment trust domains never federate by default"
          ],
          [
            "delegated-background-job",
            "Queued job acting for a previously authorized principal",
            "token_exchange",
            "workload-authority",
            "Attested workload MTLS",
            "MTLS",
            "immutable actor and subject chain; scope can only narrow; resource and command binding; single purpose and expiry; revocation checked before execution"
          ]
        ]
      },
      "bullets": [
        "Prohibited at launch: implicit, hybrid, password, authorization_code_without_pkce, shared_client_secret, unrestricted_token_exchange, device_authorization_at_launch.",
        "Authorization response validates state, nonce and issuer; redirect URI uses exact match. Tokens are never accepted from query or fragment.",
        "Sender constraint is a selected deployment profile, never an opportunistic fallback: mTLS for confidential/service clients; a separately approved DPoP profile may be used only where mTLS is impractical and its nonce/replay storage is proven."
      ]
    },
    {
      "id": "production-short-lived-credentials",
      "title": "Short-lived credentials",
      "table": {
        "caption": "Maximum credential and session lifetimes",
        "columns": [
          "Artifact",
          "Maximum",
          "Rotation/revocation rule"
        ],
        "rows": [
          [
            "Authorization code",
            "60s",
            "Single use; PKCE and client bound"
          ],
          [
            "PAR request_uri",
            "60s",
            "Single use; exact client and redirect binding"
          ],
          [
            "Human access token",
            "300s",
            "Sender constrained; no browser JavaScript storage"
          ],
          [
            "Service access token",
            "300s",
            "mTLS-bound; no refresh token"
          ],
          [
            "Privileged access token",
            "180s",
            "Live PDP check and fresh step-up"
          ],
          [
            "BFF refresh/session",
            "8h absolute · 30m idle",
            "One-time refresh rotation; family revoke on reuse"
          ],
          [
            "Privileged session",
            "15m",
            "JIT operation allowlist; no standing elevation"
          ],
          [
            "X.509-SVID",
            "<= 60m",
            "Streamed rotation; private key remains workload-local"
          ]
        ]
      },
      "bullets": [
        "Validate exact issuer, audience, authorized party/client, signature algorithm and key ID, expiry, not-before, issued-at, sender constraint, token ID, entitlement version and environment. Unknown issuer/key/scope or stale authorization fails closed.",
        "Asymmetric keys are HSM/KMS backed, have named owners and rotate on an approved schedule with tested current/next overlap; private material never enters source, image, environment dump, URL, log or evidence payload.",
        "Human disable, service disable, key compromise and privileged-grant withdrawal reach the PDP immediately and every resource server within five minutes; privileged operations always consult live entitlement state."
      ]
    },
    {
      "id": "production-scopes",
      "title": "OAuth scopes",
      "lead": "Scope является client/token ceiling, а не окончательным разрешением. Wildcard scope отсутствует; server authorizes только пересечение registration, token, current role и resource policy.",
      "table": {
        "caption": "Canonical scope families",
        "columns": [
          "Family",
          "Exact scopes",
          "Privileged scopes"
        ],
        "rows": [
          [
            "identity",
            "identity:profile:read",
            "none"
          ],
          [
            "eligibility",
            "eligibility:read, eligibility:evaluate, eligibility:review",
            "eligibility:review"
          ],
          [
            "checkout",
            "checkout:read, checkout:write",
            "none"
          ],
          [
            "deal",
            "deal:read, deal:write, deal:approve",
            "deal:approve"
          ],
          [
            "onboarding",
            "onboarding:read, onboarding:write, onboarding:review",
            "onboarding:review"
          ],
          [
            "provider",
            "provider:read, provider:operate, provider:approve",
            "provider:operate, provider:approve"
          ],
          [
            "webhook",
            "webhook:read, webhook:manage, webhook:replay",
            "webhook:manage, webhook:replay"
          ],
          [
            "evidence",
            "evidence:read",
            "none"
          ],
          [
            "audit",
            "audit:export",
            "audit:export"
          ],
          [
            "reporting",
            "reporting:read, reporting:prepare",
            "reporting:prepare"
          ],
          [
            "iam",
            "iam:read, iam:manage, iam:review",
            "iam:read, iam:manage, iam:review"
          ],
          [
            "runtime",
            "runtime:read, runtime:operate",
            "runtime:read, runtime:operate"
          ],
          [
            "security",
            "security:respond",
            "security:respond"
          ],
          [
            "support",
            "support:inspect",
            "support:inspect"
          ],
          [
            "production",
            "production:activate",
            "production:activate"
          ]
        ]
      },
      "callout": {
        "tone": "warning",
        "title": "OpenAPI ещё описывает текущий bearer runtime",
        "description": "Operation-to-scope annotations добавляются только вместе с принятым Production authorization adapter. Публикация target scopes заранее как действующей security scheme была бы ложной capability claim."
      }
    },
    {
      "id": "production-rbac",
      "title": "RBAC + resource policy",
      "lead": "RBAC задаёт стабильные job functions; ABAC/PDP сужает их по tenant, organization, environment, resource owner, mandate, amount, provider connection, data class и maker-checker history.",
      "table": {
        "caption": "Canonical role grants",
        "columns": [
          "Role",
          "Principal type",
          "Scope grants",
          "Mandatory constraint"
        ],
        "rows": [
          [
            "corporate:maker",
            "HUMAN",
            "identity:profile:read, eligibility:read, eligibility:evaluate, checkout:read, checkout:write, deal:read, deal:write, provider:read, provider:operate, evidence:read",
            "Mandate, amount, connection and resource ownership; cannot approve own command."
          ],
          [
            "corporate:approver",
            "HUMAN",
            "identity:profile:read, eligibility:read, checkout:read, deal:read, deal:approve, provider:read, provider:approve, evidence:read",
            "Independent checker; cannot prepare the command being approved."
          ],
          [
            "corporate:compliance",
            "HUMAN",
            "identity:profile:read, eligibility:read, eligibility:review, deal:read, onboarding:read, onboarding:review, evidence:read, reporting:read",
            "Review authority only; no deal preparation or provider execution scope."
          ],
          [
            "corporate:auditor",
            "HUMAN",
            "identity:profile:read, eligibility:read, checkout:read, deal:read, onboarding:read, provider:read, webhook:read, evidence:read, reporting:read, iam:read, audit:export",
            "Read-only; export requires a separately approved bounded operation."
          ],
          [
            "corporate:admin",
            "HUMAN",
            "identity:profile:read, iam:read, iam:manage",
            "May propose tenant membership and roles; cannot approve own grant or perform business commands."
          ],
          [
            "onboarding:owner",
            "HUMAN",
            "identity:profile:read, onboarding:read, onboarding:write",
            "Own organization draft only; no review of own submission."
          ],
          [
            "onboarding:editor",
            "HUMAN",
            "identity:profile:read, onboarding:read, onboarding:write",
            "Assigned organization draft only; no review scope."
          ],
          [
            "onboarding:reviewer",
            "HUMAN",
            "identity:profile:read, onboarding:read, onboarding:review",
            "Independent reviewer; creator/updater cannot review the same version."
          ],
          [
            "developer:admin",
            "HUMAN",
            "identity:profile:read, webhook:read, webhook:manage, webhook:replay, evidence:read",
            "Exact tenant and environment; production secret/replay changes remain privileged operations."
          ],
          [
            "submission:operator",
            "HUMAN / SERVICE",
            "identity:profile:read, reporting:read, reporting:prepare, evidence:read",
            "Draft preparation only unless an independently activated official transport scope exists."
          ],
          [
            "retail:buyer",
            "HUMAN",
            "identity:profile:read, checkout:read, checkout:write, deal:read, deal:write",
            "Own subject and admission grant only; no privileged read or approval."
          ],
          [
            "deal:reader",
            "HUMAN / SERVICE",
            "identity:profile:read, deal:read, evidence:read",
            "Explicit resource assignment; no tenant-wide inference from the role name."
          ],
          [
            "platform:operator",
            "HUMAN",
            "identity:profile:read, runtime:read, runtime:operate, evidence:read",
            "No tenant data by default; maintenance is JIT and ticket-bound."
          ],
          [
            "security:operator",
            "HUMAN",
            "identity:profile:read, iam:read, iam:review, security:respond, audit:export",
            "Incident and IAM checker duties; cannot silently assume tenant business roles."
          ],
          [
            "support:readonly",
            "HUMAN",
            "identity:profile:read, support:inspect, evidence:read",
            "One tenant, one ticket and at most 60 minutes; safe projections only."
          ],
          [
            "release:operator",
            "HUMAN / SERVICE",
            "identity:profile:read, runtime:read, production:activate",
            "Protected environment and release digest binding; cannot approve own activation."
          ],
          [
            "audit:reviewer",
            "HUMAN",
            "identity:profile:read, iam:read, iam:review, evidence:read, audit:export",
            "Independent review and export approval; no mutable business scope."
          ]
        ]
      },
      "bullets": [
        "Decision = intersection of registered client scope, token scope, current role grant and resource policy; any missing or unknown input is DENY.",
        "Maker and approver permissions are not combined in one business role. A principal cannot approve a command, role grant, replay or activation it prepared.",
        "Service identities receive direct exact scopes and resource bindings; importing human roles into a workload token is prohibited."
      ]
    },
    {
      "id": "production-tenant-isolation",
      "title": "Tenant isolation",
      "table": {
        "caption": "Defence-in-depth tenant boundary",
        "columns": [
          "Layer",
          "Required control",
          "Mandatory negative evidence"
        ],
        "rows": [
          [
            "FEDERATION_REGISTRY",
            "An exact issuer and client registration maps to one tenant and canonical environment. Dynamic issuer, JWKS URI, redirect URI and tenant selection are prohibited.",
            "Unknown issuer, issuer reused for an unapproved tenant, metadata redirect, JWKS host change and cross-environment client are rejected."
          ],
          [
            "TOKEN_VALIDATION",
            "Resource servers validate issuer, audience, client/authorized party, time, signature algorithm, key, sender constraint and entitlement version before resolving membership.",
            "Wrong audience, expired/future token, algorithm downgrade, unknown key, replayed proof and stale entitlement version are rejected."
          ],
          [
            "HTTP_CONTEXT",
            "Authentication middleware creates one immutable identity context. Tenant, organization, principal, environment and roles are server-derived; conflicting body/header/query assertions fail closed.",
            "Caller-supplied tenant_id, duplicate Authorization, mixed checkout/operator credentials and conflicting organization are rejected without existence disclosure."
          ],
          [
            "POLICY_DECISION_POINT",
            "Authorization is the intersection of registered client ceiling, token scopes, current role grants and resource attributes including tenant, organization, environment, mandate, owner and maker-checker history.",
            "Scope-only, role-only, stale-cache, self-approval, resource-owner mismatch and environment escalation are denied."
          ],
          [
            "POSTGRESQL_RLS",
            "Every tenant relation uses composite tenant keys, transaction-local tenant context and FORCE RLS. Runtime roles are not owners and have no superuser, BYPASSRLS, DDL or inherited elevated membership.",
            "Cross-tenant read/write, unset tenant context, direct table mutation, owner/BYPASSRLS startup and connection-pool context leakage are denied."
          ],
          [
            "ASYNC_AND_CACHE",
            "Queue, inbox, outbox, cache, idempotency and object-storage identities include the authoritative tenant/environment boundary; workers re-authorize before external or privileged effects.",
            "Cross-tenant cache keys, foreign queue records, reused idempotency keys, stale delegated grants and object references from another tenant are quarantined or denied."
          ],
          [
            "SUPPORT_ACCESS",
            "Internal support has no implicit tenant membership. Access names one tenant, case, purpose, safe data projection, approver and expiry and is visible to the tenant audit trail.",
            "Standing global support, hidden impersonation, multi-tenant query, expired JIT grant and access without ticket/approval are denied and alerted."
          ]
        ]
      }
    },
    {
      "id": "production-privileged-operations",
      "title": "Privileged operations",
      "lead": "Privileged capability is absent by default and issued just in time for one ticket and operation family. Every operation requires a fresh phishing-resistant step-up and a different checker; role possession alone is insufficient.",
      "table": {
        "caption": "JIT maker-checker controls",
        "columns": [
          "Operation",
          "Action",
          "Required scopes",
          "Max elevation",
          "Evidence"
        ],
        "rows": [
          [
            "IDP_TRUST_CHANGE",
            "Add, change, disable or rotate issuer, metadata, redirect URI, JWKS or SCIM trust.",
            "iam:manage + iam:review",
            "30m; step-up <= 5m",
            "ticket; before/after digest; maker and checker; conformance plus rollback result"
          ],
          [
            "PRIVILEGED_ROLE_GRANT",
            "Grant, extend or remove a privileged human role or JIT eligibility.",
            "iam:manage + iam:review",
            "60m; step-up <= 5m",
            "ticket and business reason; subject and role; maker and checker; expiry and revocation observation"
          ],
          [
            "SERVICE_IDENTITY_CHANGE",
            "Create, rescope, rotate, disable or delete a service identity.",
            "iam:manage + iam:review",
            "60m; step-up <= 5m",
            "owner; client/workload identity; scope and audience diff; rotation or disable proof"
          ],
          [
            "PRODUCTION_ACTIVATION",
            "Activate a capability or external-effect route in Production.",
            "production:activate + iam:review",
            "30m; step-up <= 5m",
            "release digest; closed activation gates; maker and checker; rollback and post-change observation"
          ],
          [
            "PROVIDER_CREDENTIAL_BINDING",
            "Bind, rotate, revoke or reassign a production provider credential or account.",
            "provider:approve + security:respond",
            "30m; step-up <= 5m",
            "provider/account reference digest; vault version; maker and checker; negative old-key test"
          ],
          [
            "MANUAL_REPLAY_OR_REQUEUE",
            "Replay a delivery/event or requeue a dead-lettered operation.",
            "webhook:replay + runtime:operate",
            "30m; step-up <= 5m",
            "incident/change ticket; immutable source digest/range; maker and checker; bounded outcome and reconciliation"
          ],
          [
            "TENANT_DATA_EXPORT",
            "Export restricted tenant evidence or audit data.",
            "audit:export + iam:review",
            "30m; step-up <= 5m",
            "purpose and legal basis reference; tenant/data/time range; maker and checker; encrypted artifact expiry and access log"
          ],
          [
            "AUDIT_OR_RETENTION_POLICY_CHANGE",
            "Change audit destination, retention, legal hold or evidence integrity policy.",
            "iam:review + audit:export",
            "30m; step-up <= 5m",
            "policy diff; owner approvals; maker and checker; validation and rollback result"
          ],
          [
            "BREAK_GLASS_SESSION",
            "Open emergency access when the normal control plane is unavailable.",
            "security:respond + runtime:operate",
            "15m; step-up <= 5m",
            "declared incident; two hardware-bound custodians; complete command/session record; credential replacement and next-day review"
          ]
        ]
      },
      "bullets": [
        "Self-approval, standing global admin, hidden impersonation, shared break-glass account and elevation without expiry are prohibited.",
        "The immutable receipt binds tenant/environment, subject, actor, maker, checker, scopes, resource, reason, ticket, before/after digest, issued/expiry time and outcome.",
        "Expiry removes authority automatically. Cleanup/revocation evidence is part of completion, not a separate optional task."
      ]
    },
    {
      "id": "production-access-reviews",
      "title": "Access reviews",
      "table": {
        "caption": "Review cadence and evidence",
        "columns": [
          "Review",
          "Cadence",
          "Scope",
          "Independent reviewer",
          "Evidence"
        ],
        "rows": [
          [
            "event-driven-jml",
            "CONTINUOUS; leaver and critical role removal SLA <= 5 minutes",
            "Human memberships, group mappings, active sessions and JIT grants",
            "Tenant or CertaRail IAM owner matching the identity authority",
            "SCIM event ID; before/after entitlement digest; session revocation result; completion timestamp and SLA"
          ],
          [
            "monthly-privileged-and-service",
            "MONTHLY",
            "Privileged-role eligibility, service clients, workload identities, keys/certificates, owners and last use",
            "Security owner plus independent system owner",
            "immutable population snapshot; owner attestations; unused/orphaned findings; revocations, exceptions and due dates"
          ],
          [
            "quarterly-all-human-access",
            "QUARTERLY",
            "Every human tenant membership, role, scope ceiling, resource assignment and separation-of-duties conflict",
            "Tenant access owner; privileged reviewers cannot certify themselves",
            "snapshot digest and as-of time; reviewer identities; decision per principal; completed removals and tracked exceptions"
          ],
          [
            "semiannual-federation-trust",
            "SEMIANNUAL AND BEFORE MATERIAL FEDERATION CHANGE",
            "Issuers, metadata, redirect URIs, JWKS/certificates, SCIM clients, OAuth clients, audiences and trust domains",
            "IAM architect plus Security checker",
            "registered trust inventory; metadata/key fingerprints; conformance and negative-test report; approved changes and rollback evidence"
          ],
          [
            "post-incident-review",
            "WITHIN 1 BUSINESS DAY AFTER BREAK-GLASS; WITHIN 5 BUSINESS DAYS AFTER OTHER IAM INCIDENTS",
            "Incident grants, authentication events, token/client use, commands, exports and containment",
            "Incident commander plus independent Security/Audit reviewer",
            "incident timeline; principal/token/session correlation; commands and accessed scope; revocation, credential replacement and actions"
          ]
        ]
      },
      "bullets": [
        "Review population is generated from authoritative memberships, client registrations, JIT eligibility, keys/certificates and last-use data; spreadsheets without a signed snapshot digest are not authoritative.",
        "Every decision is CERTIFY, REVOKE or TIME_BOUND_EXCEPTION with owner and due date. Missing reviewer or overdue exception fails the affected privileged activation closed.",
        "Review completion means removals propagated to sessions/tokens/PDP and were observed, not merely that a ticket was closed."
      ]
    },
    {
      "id": "production-activation-evidence",
      "title": "Activation gates и acceptance evidence",
      "table": {
        "caption": "Open Production IAM gates",
        "columns": [
          "Gate",
          "Owner",
          "Status",
          "Required evidence"
        ],
        "rows": [
          [
            "IAM_IDP_SELECTED_AND_CONFORMANT",
            "IAM Architecture",
            "OPEN",
            "Named products/deployments, FAPI 2.0/OIDC conformance result, exact issuer metadata and ownership."
          ],
          [
            "IAM_RUNTIME_ADAPTER_IMPLEMENTED",
            "Application Security",
            "OPEN",
            "OIDC/JWKS, mTLS/DPoP, token exchange and SCIM adapters with negative tests; OpenAPI updated only after runtime acceptance."
          ],
          [
            "IAM_PDP_POLICY_ENFORCED",
            "Application Security",
            "OPEN",
            "Operation-to-scope registry, RBAC/ABAC decisions, live revocation and self-approval denial tests."
          ],
          [
            "IAM_TENANT_ISOLATION_PROVEN",
            "Security Engineering",
            "OPEN",
            "HTTP, cache/queue and PostgreSQL FORCE RLS cross-tenant suite using non-owner/non-BYPASSRLS runtime roles."
          ],
          [
            "IAM_PRIVILEGED_ACCESS_EXERCISED",
            "Security Operations",
            "OPEN",
            "JIT, step-up, maker-checker, expiry, emergency access and audit drill with denied bypass attempts."
          ],
          [
            "IAM_ACCESS_REVIEW_COMPLETED",
            "IAM Governance",
            "OPEN",
            "One complete monthly and quarterly review cycle with removals, exceptions, SLA and immutable evidence."
          ],
          [
            "IAM_SECURITY_ACCEPTANCE_COMPLETE",
            "CISO delegate",
            "OPEN",
            "Threat-model update, external penetration test, incident/revocation drill, residual-risk acceptance and production activation record."
          ]
        ]
      },
      "callout": {
        "tone": "critical",
        "title": "Production IAM не активирован",
        "description": "Все gates имеют статус OPEN. До их закрытия Local bearer, mock principal и design JSON не подтверждают federated identity, MFA, workload attestation, runtime authorization, revocation SLA, access review или production tenant isolation."
      }
    }
  ]
}
