Relationships and runtime flow
Target audience: Solution Architects, Enterprise Architects, Platform Implementers
Reading time: 12 minutes
Prerequisites: Entity reference
Introduction
This page describes how the twelve entities of the deployment organization model compose: structurally (who contains whom), through control bindings (who is authorized to do what), and at runtime (how a cryptographic invocation is evaluated).
Three views are presented:
- Structural hierarchy — organizational containment
- Control composition — how authorization binds identity, resource, and context
- Runtime decision flow — how a cryptographic request is evaluated layer by layer
Structural hierarchy
The organizational layer establishes structural ownership: a chain of containment from the deployment down to the credentials that authenticate runtime actors.
flowchart TB
DEP["Deployment<br/><i>regulatory frame</i>"]
TEN["Tenant<br/><i>cryptographic domain</i>"]
APP["Application<br/><i>business container</i>"]
ACT["Cryptographic Actor<br/><i>operational subject</i>"]
CRED["Credential<br/><i>authentication mechanism</i>"]
DEP -->|contains| TEN
TEN -->|contains| APP
APP -->|contains| ACT
ACT -->|holds| CRED
style DEP fill:#e8f4f8,stroke:#1a5276,stroke-width:2px
style TEN fill:#d6eaf8,stroke:#2980b9,stroke-width:2px
style APP fill:#d5f5e3,stroke:#1e8449,stroke-width:2px
style ACT fill:#fdebd0,stroke:#d68910,stroke-width:2px
style CRED fill:#fadbd8,stroke:#c0392b,stroke-width:2px Each level constrains the level below: a deployment defines the regulatory frame within which tenants operate; a tenant scopes the applications it owns; an application contextualizes the actors that act under it; an actor holds the credentials it uses to authenticate.
This hierarchy is rigid by design. It is the structural foundation of multi-tenant isolation: an actor cannot exist outside an application, an application cannot exist outside a tenant, a tenant cannot exist outside a deployment.
Control composition
The control layer binds the structural and resource entities into authorization decisions. The Capability Grant is the convergence point.
flowchart LR
ACT["Cryptographic Actor"]
GRANT["Capability Grant"]
CAP["Capability<br/><i>encrypt / decrypt /<br/>sign / verify / wrap</i>"]
ASSET["Cryptographic Asset<br/><i>key material</i>"]
CTX["Exchange Context<br/><i>business interaction</i>"]
CONSTR["Constraint Policy<br/><i>time / volume / scope</i>"]
ACT -->|holds| GRANT
GRANT -->|invokes| CAP
GRANT -->|targets| ASSET
GRANT -->|scoped to| CTX
GRANT -->|restricted by| CONSTR
style ACT fill:#fdebd0,stroke:#d68910,stroke-width:2px
style GRANT fill:#fadbd8,stroke:#c0392b,stroke-width:3px
style CAP fill:#d5f5e3,stroke:#1e8449
style ASSET fill:#d5f5e3,stroke:#1e8449
style CTX fill:#d6eaf8,stroke:#2980b9
style CONSTR fill:#fadbd8,stroke:#c0392b A Capability Grant composes five elements into a single authorization record:
| Element | Provides | Layer |
|---|---|---|
| Actor | Identity (who) | Operational identity |
| Capability | Action (what) | Cryptographic resource |
| Asset | Resource (on what) | Cryptographic resource |
| Exchange Context | Business interaction (in which scenario) | Governed exchange |
| Constraint Policy | Conditions (under which rules) | Control |
This composition enables fine-grained authorization decisions that reflect the full governance reality, not only access control. The grant is the smallest unit of authorization that can be revoked, suspended, or audited as an atomic decision.
Entity relationship overview
The full entity-relationship model expresses how all twelve entities relate:
erDiagram
DEPLOYMENT ||--o{ TENANT : contains
DEPLOYMENT ||--o{ POLICY : "defines baseline"
TENANT ||--o{ APPLICATION : contains
TENANT ||--o{ CRYPTOGRAPHIC_ASSET : owns
TENANT ||--o{ POLICY : refines
APPLICATION ||--o{ CRYPTOGRAPHIC_ACTOR : contains
APPLICATION ||--o{ EXCHANGE_CONTEXT : owns
CRYPTOGRAPHIC_ACTOR ||--o{ CREDENTIAL : "authenticates with"
CRYPTOGRAPHIC_ACTOR ||--o{ CAPABILITY_GRANT : holds
CAPABILITY_GRANT }o--|| CAPABILITY : invokes
CAPABILITY_GRANT }o--o{ CRYPTOGRAPHIC_ASSET : targets
CAPABILITY_GRANT }o--o| EXCHANGE_CONTEXT : "scoped to"
CAPABILITY_GRANT ||--o{ CONSTRAINT_POLICY : "restricted by"
CAPABILITY_GRANT ||--o{ AUDIT_EVENT : produces
DEPLOYMENT {
string compliance_region
string hsm_provider
}
TENANT {
uuid tenant_id
string name
}
APPLICATION {
uuid app_id
string business_unit
string risk_level
}
CRYPTOGRAPHIC_ACTOR {
uuid actor_id
string type
}
CREDENTIAL {
uuid credential_id
string mechanism
}
EXCHANGE_CONTEXT {
uuid context_id
string counterparty
string direction
string sensitivity
}
CRYPTOGRAPHIC_ASSET {
string asset_id
string algorithm
string lifecycle_state
}
CAPABILITY {
string operation
}
CAPABILITY_GRANT {
uuid grant_id
}
CONSTRAINT_POLICY {
uuid constraint_id
string type
}
POLICY {
uuid policy_id
string scope
}
AUDIT_EVENT {
uuid event_id
timestamp ts
string outcome
} Reading the diagram:
- Containment relationships (Deployment → Tenant → Application → Actor) express ownership and isolation
- Composition relationships (Capability Grant → Capability, Asset, Exchange Context, Constraint Policy) express authorization
- Production relationships (Capability Grant → Audit Event) express evidence
- Policy relationships (Deployment → Policy, Tenant → Policy) express the layered governance baseline
Runtime authorization flow
When an actor invokes a capability, the control plane evaluates the request against the full governance graph before any cryptographic operation is executed. This evaluation traverses the layers in sequence.
flowchart TB
REQ["Capability invocation request<br/><i>from Cryptographic Actor</i>"]
AUTH["Authenticate Actor<br/>via Credential"]
STATUS_CHECK{"Effective status ACTIVE?<br/><i>tenant ∧ application ∧ actor (fail-closed)</i>"}
GRANT_CHECK{"Capability Grant<br/>exists for Actor?"}
CTX_CHECK{"Exchange Context<br/>active and valid?"}
CONSTR_CHECK{"Constraints satisfied?<br/><i>time / volume / scope</i>"}
POL_CHECK{"Policy compliant?<br/><i>algorithm / lifecycle / region</i>"}
EXEC["Execute capability<br/>inside HSM boundary"]
DENY["Deny operation"]
AUDIT["Emit Audit Event<br/><i>signed, immutable</i>"]
REQ --> AUTH
AUTH --> STATUS_CHECK
STATUS_CHECK -->|No| DENY
STATUS_CHECK -->|Yes| GRANT_CHECK
GRANT_CHECK -->|No| DENY
GRANT_CHECK -->|Yes| CTX_CHECK
CTX_CHECK -->|No| DENY
CTX_CHECK -->|Yes| CONSTR_CHECK
CONSTR_CHECK -->|No| DENY
CONSTR_CHECK -->|Yes| POL_CHECK
POL_CHECK -->|No| DENY
POL_CHECK -->|Yes| EXEC
EXEC --> AUDIT
DENY --> AUDIT
style REQ fill:#fdebd0,stroke:#d68910
style EXEC fill:#d5f5e3,stroke:#1e8449,stroke-width:2px
style DENY fill:#fadbd8,stroke:#c0392b,stroke-width:2px
style AUDIT fill:#e8daef,stroke:#7d3c98,stroke-width:2px Decision steps
| Step | What is evaluated | Outcome on failure |
|---|---|---|
| 1. Authenticate actor | Does the credential resolve to a valid, active Cryptographic Actor? | Reject with authentication error |
| 2. Effective-status containment | Is the full containment chain ACTIVE — tenant ∧ application ∧ actor (within an ACTIVE deployment)? Evaluated in that order (tenant → application → actor), fail-closed: if the status cannot be resolved from its source, deny. The same check also gates the interoperability and migration planes, which hold no Capability Grant and therefore never reach step 3. | Deny with reason: application-suspended / actor-suspended (HTTP 403) — never NO_GRANT. (Token issuance denies the same condition earlier as APPLICATION_NOT_ACTIVE / ACTOR_NOT_ACTIVE.) |
| 3. Capability Grant lookup | Does the actor hold a grant for this capability and asset? | Deny with reason: NO_GRANT |
| 4. Exchange Context validation | Is the bound Exchange Context ACTIVE? Is the operation within the context's effective period? | Deny with reason: CONTEXT_INACTIVE |
| 5. Constraint check | Is the request inside the owning Exchange's effective window, and is the Constraint Policy version the grant pinned satisfied (time window, usage count, rate limit, single use)? The windows are checked first, then the rate (in Redis), then the usage count and single use, which are charged durably in PostgreSQL. Each charge is check-then-charge in one atomic step: an admitted invocation is charged even if the operation then fails; a refused one is charged nothing durable | Deny with reason: CONSTRAINT_VIOLATION and the specific constraint |
| 6. Policy check | Is the operation compliant with active Policies (algorithm catalog, lifecycle state, compliance region)? | Deny with reason: POLICY_VIOLATION |
| 7. Execute | Cryptographic operation runs inside the HSM boundary | Result returned to actor |
| 8. Audit | Audit Event emitted with full decision context | Always — for both ALLOW and DENY |
Both allow and deny outcomes produce audit events. The evidence layer captures the full decision context, not only successful operations. A denied invocation produces a record explaining why — including which constraint failed and what value triggered the failure.
Determinism and ordering
The decision steps are evaluated in this fixed order. Earlier checks short-circuit later ones — a failed effective-status containment check never proceeds to grant lookup, and a failed Capability Grant lookup never proceeds to constraint evaluation. This ordering is deterministic and audit-friendly: the failure reason in an audit record always points to the first failing check.
The ordering is also defense-in-depth aligned. Identity checks (actor authentication + effective-status containment + grant) happen before resource checks (asset state, policy compliance), and structural checks happen before computational checks. This minimizes work performed on requests that will ultimately be denied.
Effective-status containment is enforced twice (defense-in-depth). The same tenant ∧ application ∧ actor condition is checked at token issuance (the client_credentials grant is refused unless the whole chain is ACTIVE — reasons TENANT_NOT_ACTIVE / APPLICATION_NOT_ACTIVE / ACTOR_NOT_ACTIVE, or fail-closed SUBJECT_STATE_UNRESOLVED on an unresolvable association) and again at the crypto seam (step 2 above), so a JWT minted while the chain was ACTIVE stops working the moment any link is suspended — it does not stay valid until expiry. The containment status is resolved fail-closed: an unresolvable status denies rather than permits.
Application deletion is a terminal cascade (not a status flag)
The effective-status containment chain above governs the reversible runtime controls: suspending a Tenant, Application, or Actor flips a single status flag and rewrites no child entity — the AND re-composition denies operations live, and reactivation restores service because nothing below was mutated.
Deleting an Application is the opposite: a terminal, irreversible cascade. It does not set a status flag to be re-composed at read time; it drives every contained entity to its terminal state and archives the application's keys. There is no refuse-if-dependents guard — active Actors, Exchange Contexts, Cryptographic Exchanges, or Internal Crypto Use Cases do not block the delete. The cascade runs in dependency order, each step independent and best-effort:
- Resolve the application's owned key identifiers (KIDs) first.
- Revoke the Internal Crypto Use Cases.
- Revoke the Capability Grants.
- Close the Exchange Contexts.
- Revoke the Cryptographic Exchanges (
REVOKED, soft-deleted). - Disable the Cryptographic Actors — including the non-deletable Default Actor (
isDefaultdoes not block). - Archive the application's non-shared keys — material retained, never destroyed; a key shared with another still-active aggregate keeps its real current status.
In short: SUSPEND is a reversible status-only control with no child rewrite, while DELETE is a one-way cascade that terminally rewrites the children and archives the keys. The retired aggregate stays inspectable through a read-only retired-applications surface. For the per-entity terminal states, see Entity reference — Application.
Composition example
A concrete invocation traversing the model:
sequenceDiagram
participant TP as Third party<br/>(visa-embossing-actor)
participant CCP as ANKASecure©<br/>Control Plane
participant POL as Policy engine
participant HSM as HSM<br/>(owner's domain)
participant AUD as Audit log
TP->>CCP: decrypt(asset=embossing-key-visa, ciphertext)
CCP->>POL: Evaluate grant + context + constraints + policy
POL-->>CCP: ALLOW (with applied constraints)
CCP->>HSM: Execute decrypt inside HSM
HSM-->>CCP: Plaintext result
CCP->>AUD: Log allow with full context
CCP-->>TP: Plaintext (key never leaves HSM) Key points:
- The actor never receives the key — only the operational result
- The HSM never exposes raw key material to the control plane
- Every step that produces a decision is captured in audit
- The decision is contextualized to the Exchange Context (Embossing — VISA), so the same actor in a different context would have different authorizations
Next steps
- For worked examples of these flows in concrete enterprise scenarios, see Reference scenarios.
- For a detailed reference to the entities involved, see Entity reference.
- For the conceptual layer breakdown, see The six-layer model.