JanssenProject / JanssenProject/jans
feat(jans-cedarling): Cedarling Sidecar TRACE Evidence Producer Design
- Dominant language
- Java
- Stars
- 647
- Forks
- 173
- Avg merge
- 1d 18h
- Merged PRs (30d)
- 110
Description
## 1. Summary
This design extends the Cedarling sidecar to produce cryptographically bound evidence fragments that Jans Lock Server can use to construct TRACE v0.2 Trust Records.
Cedarling is the correct source for workload-local authorization evidence because it knows which policy store made each decision, which tokens were evaluated, and whether the decision was allowed or denied. With the proposed runtime-attestation module, it can also bind this evidence to an independently appraised confidential-computing environment.
Cedarling does not create the complete TRACE Trust Record. It produces ordered, signed evidence for facts it can observe and accepts authenticated execution events for facts reported by the application or gateway. Lock Server correlates these fragments with identity, attestation, model, build, and transparency evidence and constructs the record.
## 2. Trust boundary
```mermaid
flowchart TD
APP["Application / agent gateway"] -->|tool events| CS["Cedarling sidecar"]
AS["Jans Auth Server"] -->|JWT-SVID| CS
ATS["Attestation Token Service"] -->|appraisal token| CS
CS -->|signed TRACE evidence| LOCK["Jans Lock Server"]
LOCK -->|record digest to sign| CS
CS -->|TEE-key signature| LOCK
```
Cedarling may assert directly:
- Which authorization request it evaluated.
- Which decision it returned.
- Which policy store and policy artifact it used.
- Which validated token identities participated.
- Which Attestation Token it validated.
- Which events arrived through its authenticated evidence interface.
Cedarling must not claim direct observation of model execution, tool completion, tool output, or physical effects unless it actually mediates that boundary.
## 3. Goals
- Produce deterministic TRACE evidence for a bounded execution execution.
- Bind authorization decisions to the exact Cedar policy bundle.
- Bind runtime appraisal to the workload identity and signing key.
- Commit to an ordered tool transcript without exposing sensitive payloads.
- Preserve data-classification changes across the execution.
- Sign evidence with a TEE-bound key.
- Deliver evidence reliably to Lock Server.
- Support a Lock-generated record-signing request without exporting the private key.
- Preserve existing AuthZEN behavior when TRACE is disabled.
## 4. Non-goals
- Long-term evidence storage.
- TRACE search, reporting, or auditor APIs.
- SCITT anchoring.
- Authoritative verification of hardware evidence.
- Verification of SLSA provenance.
- Inferring model identity from application behavior.
- Proving that an allowed operation produced its claimed external effect.
## 5. Identifier model
`trace_execution_id` identifies one governed agent execution. It is distinct from an Auth Server login session, OAuth transaction, JWT `jti`, Cedarling decision, and individual tool call.
| Identifier | Owner | Purpose |
| --- | --- | --- |
| `trace_execution_id` | Application/gateway; Cedarling fallback | Groups the evidence that becomes one TRACE record. |
| Auth Server `sid` | Jans Auth Server | Correlates authentication or SSO state only. |
| JWT-SVID `jti` | Jans Auth Server | Identifies one workload credential. |
| Attestation Token `jti` | ATS | Identifies one runtime appraisal token. |
| `decision_id` | Cedarling Core | Identifies one policy evaluation. |
| `call_id` | Application/gateway | Correlates one tool request, authorization, and outcome. |
| `transaction_id` | Transaction owner | Correlates the broader business or OAuth transaction. |
The application or agent gateway supplies `trace_execution_id` when it knows the workflow boundary. Cedarling generates a collision-resistant fallback only when it is absent. The first signed evidence envelope registers the identifier with Lock Server.
## 6. TRACE execution lifecycle
The sidecar introduces a execution abstraction above individual `/cedarling/evaluation` calls.
```mermaid
stateDiagram-v2
[*] --> Open
Open --> Recording
Recording --> Closing: finalize
Closing --> Submitted: evidence accepted
Closing --> Pending: Lock unavailable
Pending --> Submitted: retry succeeds
Submitted --> Signed: final record digest signed
```
Every execution has:
- Globally unique `trace_execution_id`.
- Workload subject and JWT-SVID identifier.
- Attestation Token identifier.
- Model descriptor reference.
- Policy-store identifier, version, and digest.
- Start and end time.
- Highest observed data classification.
- Ordered decision and tool-event chain.
- Completeness state.
- TEE-bound signing-key identifier.
Policy reload, workload-key rotation, or attestation-subject change closes the current execution and starts another.
## 7. APIs
### 7.1 Create execution
```http
POST /cedarling/trace/executions
Content-Type: application/json
Authorization: DPoP
```
```json
{
"model": {
"provider": "example-provider",
"model_id": "example-model",
"version": "2026-09-01",
"weights_digest": "sha256:...",
"aibom_uri": "https://registry.example/aibom/..."
},
"initial_data_class": "internal",
"delegation": {
"parent_record_hash": "sha256:...",
"credential_id": "delegation-123"
}
}
```
Model and delegation metadata must be authenticated or validated against a trusted manifest. Untrusted caller declarations are labeled as declarations and cannot silently become verified facts.
### 7.2 Authorization evaluation
The existing AuthZEN endpoint remains:
```http
POST /cedarling/evaluation
TRACE-Execution-ID: sess_719c
TRACE-Call-ID: call_0042
```
The sidecar records the canonical request digest, token identifiers, policy digest, decision, decision ID, and timestamp. It does not log bearer tokens or raw sensitive context.
### 7.3 Execution event
The application or gateway reports what happened after authorization:
```http
POST /cedarling/trace/executions/sess_719c/events
```
```json
{
"call_id": "call_0042",
"sequence": 7,
"protocol": "mcp",
"tool": "payments.transfer",
"request_hash": "sha256:...",
"request_data_class": "restricted",
"response_hash": "sha256:...",
"response_data_class": "confidential",
"outcome": "completed",
"external_receipt": null
}
```
The event source must authenticate using a workload identity authorized for the execution. Cedarling records whether the event was observed directly or reported by another component.
### 7.4 Finalize execution
```http
POST /cedarling/trace/executions/sess_719c/finalize
```
Finalization freezes the event set, detects missing authorization/completion pairs, calculates transcript commitments, creates the evidence envelope, signs it, and submits it to Lock Server.
## 8. Evidence envelope
Cedarling submits a Jans-defined envelope rather than an incomplete TRACE record:
```json
{
"profile": "https://jans.io/trace/cedarling-evidence/v1",
"evidence_id": "ev_91d2",
"trace_execution_id": "sess_719c",
"producer": "spiffe://example.org/cedarling/payment-agent",
"subject": "spiffe://example.org/agent/3f9c",
"issued_at": 1788888000,
"identity": {
"jwt_svid_jti": "svid_72a",
"cnf_jkt": "9XKt..."
},
"runtime": {
"attestation_token_jti": "at_91d2",
"platform": "amd-sev-snp",
"measurement": "sha384:...",
"appraisal_status": "affirming",
"verifier": "https://verifier.example",
"policy_ref": "https://verifier.example/policies/prod-v4"
},
"policy": {
"bundle_hash": "sha256:...",
"enforcement_mode": "enforce",
"version": "1.4.2",
"policy_uri": "https://example/releases/policy.cjar"
},
"data_class": "restricted",
"tool_transcript": {
"hash": "sha256:...",
"call_count": 7,
"chain_tip": "sha256:...",
"complete": true
},
"model": {
"source": "signed-agent-manifest",
"descriptor_hash": "sha256:..."
},
"record_signing_key": {
"jwk": {"kty":"EC","crv":"P-256","x":"...","y":"..."},
"attestation_binding": "at_91d2"
},
"signature": "..."
}
```
The envelope is RFC 8785-canonicalized and signed with the TEE-bound evidence key. Lock Server verifies this signature before trusting any field.
## 9. Policy binding
Cedarling must hash the exact policy artifact used for evaluation, not a URL, mutable repository, or reconstructed policy string.
Required behavior:
- Compute SHA-256 over the exact CJAR/policy-bundle bytes after download and before loading.
- Retain the digest with the active engine instance.
- Record release version and immutable artifact URI when available.
- Default `enforcement_mode` to `enforce`.
- Require explicit configuration for `silent` or `advisory`.
- Never claim enforcement for a policy that was merely named.
- Close active TRACE executions before activating a new policy digest.
## 10. Decision and transcript evidence
Each authorization decision becomes a canonical entry:
```json
{
"sequence": 6,
"event_type": "authorization_decision",
"call_id": "call_0042",
"decision_id": "dec_82f",
"request_hash": "sha256:...",
"decision": "ALLOW",
"policy_bundle_hash": "sha256:...",
"timestamp": 1788888000
}
```
Execution events follow the decision in the same ordered chain. The sidecar maintains:
```text
entry_hash[n] = SHA-256(JCS(entry[n]) || entry_hash[n-1])
```
TRACE `tool_transcript.hash` is calculated over the RFC 8785 canonical ordered event list or a versioned transcript envelope defined by the producer profile. The chain tip supplements, but does not replace, the TRACE-required transcript hash.
The sidecar records:
- Missing completion event.
- Completion without authorization.
- Duplicate `call_id` or sequence.
- Denied call followed by reported execution.
- Late event after finalization.
- External action receipt and its issuer metadata.
## 11. Data classification
The sidecar accepts classifications only from configured trusted sources and maintains an ordered lattice such as:
```text
public < internal < confidential < restricted < secret
```
The execution-level `data_class` is the most sensitive trusted classification observed across requests and responses. A caller may raise, but may not lower, the current classification without an authorized reclassification receipt.
## 12. Runtime attestation
The sidecar's attestation module obtains and validates the Attestation Token. TRACE production additionally requires:
- Normalized platform identifier.
- Runtime measurement and RIM reference.
- Firmware/TCB information when supplied.
- Appraisal status, verifier, policy reference, and timestamp.
- Binding between the runtime evidence and TRACE record-signing key.
- Freshness nonce when requested by Lock Server.
An Attestation Token that only proves the JWT-SVID key does not automatically bind a distinct TRACE signing key. ATS must accept the TRACE public key as evidence user data or issue a binding claim covering both keys.
## 13. Final-record signing protocol
Lock Server constructs the final TRACE record, but a Level 1 record must remain signed by a key bound to the attested workload. Therefore finalization is two-phase:
1. Cedarling submits its signed evidence envelope.
2. Lock validates and correlates all evidence.
3. Lock constructs the complete TRACE record without `signature`.
4. Lock RFC 8785-canonicalizes it and returns the bytes plus record digest to Cedarling.
5. Cedarling checks the immutable fields against its execution evidence.
6. Cedarling signs the canonical bytes using the TEE-bound TRACE key.
7. Lock verifies the signature, adds it, validates the schema, and persists the record.
Cedarling must refuse to sign when subject, runtime measurement, policy hash, transcript hash, data class, model descriptor, signing JWK, or execution identifier differs from its finalized evidence.
## 14. Reliable delivery
- Submit evidence over mutually authenticated TLS or DPoP-bound OAuth.
- Assign idempotent `evidence_id` and `trace_execution_id` values.
- Retry with bounded backoff.
- Persist only encrypted, bounded retry state when Lock is unavailable.
- Reject server acknowledgements that do not identify the accepted evidence digest.
- Expose queue depth, oldest pending age, and permanent rejection metrics.
## 15. Configuration
```yaml
trace:
enabled: true
lock_server_endpoint: https://lock.example.org/trace/v1
producer_profile: https://jans.io/trace/cedarling-evidence/v1
session_timeout_seconds: 900
max_open_executions: 1000
data_class_lattice: [public, internal, confidential, restricted, secret]
transcript:
retain_payloads: false
require_completion_event: true
signing:
signer_socket: /run/jans-identity/trace-signer.sock
algorithms: [ES256]
delivery:
queue_path: /run/cedarling/trace-queue
max_queue_bytes: 104857600
```
## 16. Security requirements
- Never accept caller overrides for policy digest, authorization result, runtime appraisal, or signing key.
- Never log raw tokens, tool parameters, model prompts, responses, or evidence.
- Authenticate execution-event producers.
- Bind every event to execution, call, sequence, and producer identity.
- Reject ambiguous canonicalization and non-finite or out-of-range numeric values.
- Use an RFC 8785 implementation, not ordinary sorted JSON.
- Keep the TRACE private key non-exportable.
- Prevent final-record signing from becoming a general signing oracle.
- Mark incomplete transcripts honestly; never emit `complete: true` after gaps.
## 17. Observability
- `cedarling_trace_sessions_total{result}`
- `cedarling_trace_open_sessions`
- `cedarling_trace_events_total{type,source}`
- `cedarling_trace_transcript_gaps_total{reason}`
- `cedarling_trace_evidence_submissions_total{result}`
- `cedarling_trace_signing_requests_total{result}`
- `cedarling_trace_delivery_queue_depth`
- `cedarling_trace_delivery_oldest_seconds`
Decision logs should carry `trace_execution_id`, `call_id`, `decision_id`, `capability_id`, policy digest, evidence ID, and relevant token `jti` values.
## 18. Implementation phases
### Phase 1: Software evidence
- Execution lifecycle and correlation.
- Policy artifact hashing.
- Decision-event chain.
- Tool-event ingestion.
- Data-class aggregation.
- RFC 8785 evidence envelope and software signing.
- Lock delivery.
### Phase 2: Hardware-bound evidence
- ATS integration.
- TEE-bound TRACE signing key.
- Runtime/appraisal claims.
- Nonce and key binding.
- Two-phase final-record signing.
### Phase 3: Protocol profiles
- MCP and A2A event adapters.
- External action receipts.
- Delegation links.
- Composite application/sidecar workload measurements.
## 19. Acceptance criteria
- Disabled mode preserves current Cedarling sidecar behavior.
- Every evidence envelope validates against the Jans producer schema.
- Policy digest identifies the exact artifact evaluated.
- Transcript order and call count are deterministic.
- Missing or contradictory execution events are visible.
- Attestation binds the subject and TRACE signing key.
- Lock can verify and ingest envelopes idempotently.
- Cedarling signs only a Lock draft matching its finalized evidence.
- Test vectors cover tampering, replay, gaps, policy reload, key rotation, and Lock outage.
## 20. Key limitation
Cedarling directly observes authorization, not necessarily execution. TRACE evidence about model use, tool completion, responses, and physical outcomes remains only as trustworthy as the authenticated component that reports it. Deploying Cedarling inline at an MCP/A2A gateway strengthens this boundary; an out-of-band completion callback remains reported evidence.
Contributor guide
Assessment
This issue has not been assessed yet.