Skip to content

SPIFFE, Grants, and Security

Amendment CKP-3.1-SPIFFE-Identity

This section extends CKP v3.0 with fine-grained, cryptographically-attested cross-kernel cooperation. Every Concept Kernel is a SPIFFE workload. Every cross-kernel action requires a valid SVID. Permissions are action-scoped, time-bounded, and audited. SPIRE handles the entire certificate lifecycle automatically.

SPIFFE Identity Assignment at Mint

Every CK receives a stable SPIFFE identity at mint time. The SPIFFE ID is derived deterministically from the kernel class and GUID. It never changes for the lifetime of the Material Entity.

# SPIFFE ID format -- assigned at mint, permanent
spiffe://{domain}/ck/{kernel_class}/{guid}

# Examples:
spiffe://{domain}/ck/Finance.Employee/7f3e-a1b2-c3d4-e5f6
spiffe://{domain}/ck/CK.Query/9a1b-c2d3-e4f5-g6h7
spiffe://{domain}/ck/predicates.isDependentOn/bb3c-d4e5-f6a7-b8c9

Grants Block -- The ODRL Policy

The grants block in conceptkernel.yaml replaces all binary ck:isAccessibleBy declarations. It is the sole source of cross-CK permission truth -- and is recognised as the CKP implementation of ODRL.

Enterprise ODRL ConceptCKP Grants Block EquivalentExample
odrl:PolicyThe entire grants: blockThe kernel's complete permission declaration
odrl:Permissionactions: list for a given identityactions: [read-identity, invoke-tool]
odrl:ProhibitionAbsence from actions list = implicitly prohibitedCK not in any identity's actions -> access denied
odrl:Constraintexpires: field on a grant entryexpires: 2026-06-01T00:00:00Z
odrl:Dutyaudit: true -- obligation to log the accessEvery access written to ledger/
odrl:AssetThe kernel itself -- all three volumesTarget = ckp://Kernel#Finance.Employee:v1.0
odrl:PartySPIFFE identity string or access tierspiffe://{domain}/ck/CK.Query/...
yaml
# conceptkernel.yaml -- grants block
grants:
  - identity:  spiffe://{domain}/ck/CK.Query/9a1b-...
    actions:   [read-storage, read-index, read-llm]
    expires:   2027-01-01T00:00:00Z
    audit:     true

  - identity:  spiffe://{domain}/ck/Finance.Payroll/cc4d-...
    actions:   [read-storage, read-index]
    expires:   2026-12-31T00:00:00Z
    audit:     true

  - identity:  spiffe://{domain}/ck/CK.AuditFinal/dd5e-...
    actions:   [read-identity, read-storage, read-ledger]
    expires:   never
    audit:     true

  - identity:  spiffe://{domain}/agent/agent-kernel
    actions:   [invoke-tool, read-identity, read-skill]
    expires:   2026-06-01T00:00:00Z
    audit:     true

Seven Action Types (v3.2)

v3.2 classifies all actions into seven types that determine context assembly, output format, and instance record:

TypeVerbs / PatternContext LoadedInstance RecordBFO
inspectstatus, show, list, versionTarget identity onlyNone -- stateless--
checkcheck., validate, probe.Target + rules + schemaproof.jsonBFO:0000015
mutatecreate, update, complete, assignTarget + grants + pre-stateledger.json (before/after)BFO:0000015
operateexecute, render, run, spawn, chatFull workspacesealed instance + conversation/BFO:0000015
queryfleet.*, catalog, searchFleet-wide scanNone -- stateless--
deploydeploy., apply, route.Target + manifests + cluster statedeployment recordBFO:0000015
transferexport., import., syncSource + destination + mappingtransfer receiptBFO:0000015

Actions Not Grantable to External Identities

No external identity may ever be granted write-storage, write-tool, or any action that mutates the CK loop. These are reserved for the kernel's own runtime and the operator CI pipeline. The sovereign boundary of the Material Entity is absolute.

SVID Verification Flow

Every cross-kernel request is authenticated by SPIRE before it reaches the target CK's volumes:

1. Caller CK obtains its SVID from local SPIRE agent
   GET /run/spire/sockets/agent.sock -> X.509-SVID (valid 1h)

2. Caller presents SVID in mTLS handshake to target CK's access proxy

3. Target CK access proxy verifies:
   a. SVID signature valid against SPIRE trust bundle
   b. SVID not expired
   c. Caller SPIFFE ID present in conceptkernel.yaml grants block
   d. Requested action in granted actions list for that identity
   e. Grant not expired (expires field)

4. On success: request forwarded to the kernel's storage volume
   On failure: 403 + audit entry written to storage/ledger/audit.jsonl

5. All accesses (success + failure) appended to ledger/:
   { timestamp, caller_svid, action, path, result: allow|deny }

6. SPIRE rotates caller SVID automatically before TTL expiry

Grant Lifecycle

Lifecycle EventHow It HappensWhat Changes
Grant createdOperator edits grants block, commits to CK loop repoSPIRE entry updated; new grant active on next promotion
Grant expiresexpires field passes -- SPIRE stops issuing SVIDs for that entryNo manual action; access silently blocked
Grant revoked earlyOperator removes grant, commits + promotesSPIRE entry deleted; existing SVIDs expire within TTL (max 1h)
SVID rotationSPIRE rotates certificate automatically before 1h TTLCaller gets new cert transparently
CK decommissionedPlatform removes SPIRE entries for all three CK SVIDsAll grants to/from this CK revoked within 1h

Loop Isolation via Volume Drivers

DL BoxLoopVolume readOnlyConsequence
TBoxCKtrueRuntime process cannot modify identity or ontology
RBoxTOOLtrueRuntime process cannot modify its own code
ABoxDATAfalseRuntime process writes instances, proofs, ledger

WARNING

Volume driver readOnly makes the Separation Axiom physically impossible to violate, not merely a convention.

A storage write NEVER causes a CK commit. A tool execution NEVER modifies identity files. An identity change NEVER directly mutates stored instances.

SPIFFE and the Awakening Sequence

The awakening sequence gains a new step between reading CHANGELOG.md and reading ontology.yaml:

OrderFile / ActionQuestion Answered
1conceptkernel.yamlI am -- class, GUID, BFO:0000040
2README.mdI exist because -- purpose and goals
3CLAUDE.mdI behave like this -- rules, agreements, folder map
4SKILL.mdI can do these things -- reusable capabilities
5CHANGELOG.mdI have already become -- completed evolution
5aSPIRE agentI am cryptographically who I claim -- SVID obtained and verified
6ontology.yamlMy world has this shape -- TBox schema
7rules.shaclI am constrained by -- validation rules

NATS Topic Authentication

NATS connections from CKs require a SPIFFE JWT-SVID as the connection credential:

python
# NATS connection authenticated by SPIFFE JWT-SVID
spiffe_jwt = spire_agent.fetch_jwt_svid(audience='nats.{domain}')

nats.connect('nats://nats.{domain}:4222',
             user=f'spiffe://{domain}/ck/{class}/{guid}',
             password=spiffe_jwt)

# Subject-level ACLs derived from grants block:
#   publish:   ck.{own-guid}.*           (always allowed)
#   subscribe: ck.{other-guid}.*          (only if grant exists)

SPIFFE Infrastructure Requirements

ComponentRoleDeployment
SPIRE ServerIssues SVIDs; maintains registration entries; rotates certsSingle workload with HA via leader election
SPIRE AgentRuns on every node; provides SVID to local workloads via socketPer-node agent
CK Access ProxyIntercepts inbound cross-CK requests; verifies SVID + grantsSidecar process in every CK workload
NATS SPIFFE PluginValidates JWT-SVIDs on NATS connections; enforces topic ACLsNATS server configuration
Distributed Filesystem mTLSRequires client cert (SVID) on all filer connectionsFilesystem TLS config
Identity Provider SPIFFE bridgeLinks OIDC identity (human) to SVID (workload) in audit chainIdentity provider custom mapper

Released under the MIT License.