From 50ef39c263aa475d02136a412256d909e846a6c4 Mon Sep 17 00:00:00 2001 From: blocksifrdev Date: Mon, 11 May 2026 10:50:35 -0400 Subject: [PATCH] Harden TTP protocol MVP --- .github/workflows/ci.yml | 12 +- ASSESSMENT.md | 49 + GOVERNANCE.md | 47 + MVP.md | 62 ++ README.md | 940 +++------------- ROADMAP.md | 137 +-- SECURITY.md | 107 +- SPECIFICATION.md | 267 +++++ THREAT_MODEL.md | 27 + docs/architecture.md | 340 ++---- docs/integration-patterns.md | 52 + docs/protocol-security-model.md | 56 + docs/ttp-vs-existing-standards.md | 35 + docs/ttp-vs-rap-vs-scim-re.md | 75 ++ examples/01-basic-agent.ttp | 36 + examples/02-trust-decay.ttp | 36 + examples/03-threshold-proof.ttp | 36 + examples/04-delegated-trust.ttp | 54 + examples/05-frontdesk-authority-context.ttp | 40 + package.json | 9 +- protocol/spec.md | 1069 +------------------ src/ast.js | 21 + src/error.js | 18 + src/evaluator.js | 155 +++ src/index.js | 73 ++ src/lib.js | 39 + src/parser.js | 200 ++++ tests/ttp-cli.test.mjs | 93 ++ 28 files changed, 1846 insertions(+), 2239 deletions(-) create mode 100644 ASSESSMENT.md create mode 100644 GOVERNANCE.md create mode 100644 MVP.md create mode 100644 SPECIFICATION.md create mode 100644 THREAT_MODEL.md create mode 100644 docs/integration-patterns.md create mode 100644 docs/protocol-security-model.md create mode 100644 docs/ttp-vs-existing-standards.md create mode 100644 docs/ttp-vs-rap-vs-scim-re.md create mode 100644 examples/01-basic-agent.ttp create mode 100644 examples/02-trust-decay.ttp create mode 100644 examples/03-threshold-proof.ttp create mode 100644 examples/04-delegated-trust.ttp create mode 100644 examples/05-frontdesk-authority-context.ttp create mode 100644 src/ast.js create mode 100644 src/error.js create mode 100644 src/evaluator.js create mode 100755 src/index.js create mode 100644 src/lib.js create mode 100644 src/parser.js create mode 100644 tests/ttp-cli.test.mjs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2a2b77f..3b386bb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,7 +8,7 @@ on: jobs: verify: - name: Demo and Tests + name: CLI, Examples, and Tests runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -17,8 +17,14 @@ jobs: with: node-version: 20 + - name: Show CLI version + run: npm run ttp -- version + + - name: Check TTP examples + run: npm run check:examples + - name: Run local adoption demo run: npm run demo - - name: Run trust-routing tests - run: npm run test:trust-routing + - name: Run tests + run: npm test diff --git a/ASSESSMENT.md b/ASSESSMENT.md new file mode 100644 index 0000000..1f4f977 --- /dev/null +++ b/ASSESSMENT.md @@ -0,0 +1,49 @@ +# Repository Assessment + +## Current Maturity Level + +TTP is a promising protocol project in draft/MVP stage. After this update, the repo is more credible as an open-source protocol foundation, but it is not yet recommended for production security enforcement. + +## Strengths + +- Original protocol positioning around trust decay, proof-based authority, and trust transfer. +- Clear enterprise relevance for AI agents, non-human identities, CI/CD, service accounts, and API workflows. +- Good fit as a trust expression layer beneath runtime authority systems. +- Initial examples, CLI scaffold, tests, and docs now make the project easier to evaluate. +- Apache 2.0 licensing supports open-source adoption. + +## Gaps + +- Parser is intentionally minimal and not a complete grammar implementation. +- Proof model is `cleartext-dev`; signed and ZKP modes are future work. +- Delegation syntax exists, but delegation evaluation is not complete. +- Issuer registry and signed claim validation are not implemented. +- Runtime enforcement requires RAP, Execution Exchange, gateway, or CI integrations. +- Conformance tests need expansion before independent implementations can rely on the spec. + +## Risks + +- Overclaiming could damage enterprise credibility if production readiness is implied too early. +- Trust scores can be misunderstood as universal rather than scoped and time-bound. +- Weak issuer validation would undermine the protocol in production deployments. +- Runtime bypass remains the central integration risk. +- Clock and replay protections need careful design before production use. + +## Next Milestones + +1. Complete grammar parser and AST conformance fixtures. +2. Implement signed trust claims and issuer registry prototype. +3. Add delegation evaluator with scope, expiration, and max-score enforcement. +4. Define RAP and SCIM-RE mapping fixtures. +5. Publish security review checklist and failure-mode tests. + +## Scores + +| Area | Score | Notes | +| --- | ---: | --- | +| Protocol originality | 9/10 | Strong differentiated thesis around live, decaying trust. | +| Enterprise relevance | 8/10 | Clear fit for NHI, agent, workflow, and runtime authority problems. | +| Implementation maturity | 4/10 | MVP scaffold exists, but production semantics are incomplete. | +| Security documentation | 6/10 | Threat model and security policy now exist; hardening remains. | +| Open-source readiness | 7/10 | Better README, governance, examples, CI, and contribution path. | +| Overall enterprise readiness | 5/10 | Credible for review and prototyping, not enforcement production. | diff --git a/GOVERNANCE.md b/GOVERNANCE.md new file mode 100644 index 0000000..3596b5a --- /dev/null +++ b/GOVERNANCE.md @@ -0,0 +1,47 @@ +# Governance + +## Project Purpose + +TTP exists to define a portable trust grammar for autonomous execution: trust claims, authority context, delegation, proof requirements, and decay. It should remain interoperable and independent from any single commercial control plane. + +## Maintainer Model + +Maintainers are responsible for protocol clarity, implementation quality, security review, release integrity, and contributor onboarding. + +Security-sensitive areas require maintainer review: + +- Parser and evaluator behavior. +- Trust scoring and decay. +- Proof modes. +- Delegation semantics. +- Runtime integration contracts. +- Cryptographic verification. + +## RFC Process + +Protocol changes should use an RFC when they alter grammar, object model, evaluation semantics, proof modes, or compatibility. + +An RFC should include: + +- Problem statement. +- Proposed change. +- Syntax or data model impact. +- Security considerations. +- Compatibility and migration notes. +- Alternatives considered. + +## Versioning + +Implementation packages use semantic versioning. Protocol grammar uses explicit protocol versions. Backward-incompatible grammar changes require migration notes and conformance fixture updates. + +## Compatibility Policy + +Draft versions may change. Once a stable version is declared, conforming evaluators should continue accepting compatible prior documents or provide clear migration errors. + +## Security Review Process + +Changes touching trust semantics should include tests for invalid input, expired trust, insufficient score, unsupported proof modes, and unsafe references. Cryptographic changes require dedicated review before release. + +## Contribution Review Expectations + +PRs should be focused, documented, and testable. Maintainers may ask for smaller changes when a PR mixes protocol semantics, implementation changes, and documentation updates. diff --git a/MVP.md b/MVP.md new file mode 100644 index 0000000..fd94c67 --- /dev/null +++ b/MVP.md @@ -0,0 +1,62 @@ +# TTP MVP + +The first usable TTP implementation should be small, testable, and buildable in 30 days. It should prove the core protocol loop without claiming production security. + +## MVP Includes + +- Parse `.ttp` files. +- Validate core syntax. +- Build an AST/object model. +- Evaluate static trust score. +- Evaluate trust decay over time. +- Evaluate threshold condition. +- Output JSON evaluation result. +- Support `cleartext-dev` proof mode. +- Include at least three examples. +- Include CLI commands. + +## MVP Excludes + +- Production ZKP. +- Distributed trust network. +- Blockchain anchoring. +- Full policy marketplace. +- Complete FrontDesk integration. +- Cross-enterprise trust routing. +- Production issuer registry. +- Production runtime enforcement. + +## CLI Commands + +```bash +npm run ttp -- check examples/01-basic-agent.ttp +npm run ttp -- eval examples/02-trust-decay.ttp --subject agent:invoice_reviewer --at now +npm run ttp -- version +``` + +## Acceptance Criteria + +- `ttp check examples/01-basic-agent.ttp` succeeds. +- `ttp eval examples/02-trust-decay.ttp --subject agent:invoice_reviewer --at now` returns JSON. +- Tests pass in CI. +- Invalid syntax returns useful errors. +- Expired trust returns failed evaluation. +- Decayed trust below threshold returns failed evaluation. +- Threshold met returns valid evaluation. + +## Initial Examples + +- `examples/01-basic-agent.ttp` +- `examples/02-trust-decay.ttp` +- `examples/03-threshold-proof.ttp` +- `examples/04-delegated-trust.ttp` +- `examples/05-frontdesk-authority-context.ttp` + +## Buildable 30-Day Plan + +| Week | Work | +| --- | --- | +| 1 | Parser, AST, syntax errors, examples. | +| 2 | Trust decay evaluator and threshold evaluator. | +| 3 | CLI, JSON output, fixture tests, CI. | +| 4 | Spec cleanup, security review, contributor docs, conformance fixtures. | diff --git a/README.md b/README.md index e842c27..0733d1e 100644 --- a/README.md +++ b/README.md @@ -1,870 +1,248 @@ -# Trust Transfer Protocol (TTP) +# Trust Transfer Protocol -TTP is an open protocol for deciding whether an autonomous system should be allowed to execute a protected action right now. +[![Protocol](https://img.shields.io/badge/protocol-draft-2f6fed)](SPECIFICATION.md) +[![Reference Implementation](https://img.shields.io/badge/reference%20implementation-active%20development-f59e0b)](MVP.md) +[![Node.js](https://img.shields.io/badge/runtime-Node.js%2020-339933)](package.json) +[![Security Model](https://img.shields.io/badge/security-model%20documented-7c3aed)](THREAT_MODEL.md) +[![Production Use](https://img.shields.io/badge/production%20use-not%20recommended-b91c1c)](SECURITY.md) +[![License](https://img.shields.io/badge/license-Apache%202.0-blue)](LICENSE) -It fills the gap between **identity authentication** and **execution-time trustworthiness** by using signed behavioral evidence, trust routing, short-lived trust tokens, and verifiable execution receipts. +TTP is an open protocol and declarative language for expressing verifiable trust, authority context, delegation, and decay before autonomous systems execute. -[![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE) -[![Spec](https://img.shields.io/badge/spec-v1.0-green.svg)](protocol/spec.md) -[![Status](https://img.shields.io/badge/status-active%20development-orange.svg)](docs/roadmap.md) +It is designed for AI agents, non-human identities, automation pipelines, service accounts, APIs, and cross-system workflows where static access is not enough. ---- - -## Why Teams Adopt TTP +TTP answers one question: -Autonomous agents can hold valid credentials while their behavior is stale, risky, compromised, or outside policy. TTP adds a runtime trust gate before high-impact actions such as production deploys, customer messaging, discount issuance, code changes, and tool execution. +> Can this actor prove enough current trust to attempt this action now? -Instead of asking only "who is calling?", TTP asks: - -```text -Should this subject execute this action on this resource now? -``` +TTP does not replace IAM, SCIM, OPA, PAM, SPIFFE, OAuth, OIDC, API gateways, or policy engines. It provides the trust expression layer that runtime authority systems can evaluate before execution. -The answer is explicit: `PERMIT`, `DENY`, `STEP_UP`, `THROTTLE`, or `CONSTRAIN`, with a receipt that can be audited later. +> **Status:** Protocol specification draft complete. Reference implementation in active development. +> **Current milestone:** MVP parser + trust decay evaluator. +> **Production use:** Not yet recommended. --- -## Try It In 60 Seconds - -Run the local trust-gate demo. It has no external dependencies and shows the core adoption wedge: a protected execution request is permitted, stepped up, or denied based on current trust evidence. - -```bash -npm run demo -``` - -Expected shape: +## Why TTP Exists -```text -PERMIT trusted build action -decision: PERMIT -reason: route_valid +Modern systems increasingly delegate meaningful work to agents, pipelines, service accounts, and autonomous workflows. These actors may hold valid credentials while their trust context is stale, overbroad, delegated too far, or no longer appropriate for the action they are about to attempt. -STEP_UP production deploy -decision: STEP_UP -reason: step_up_required +Identity systems prove who an actor is. Policy engines decide whether a rule allows an action. TTP fills the gap between those layers by expressing current, scoped, decaying trust that can be evaluated before execution. -DENY revoked workload -decision: DENY -reason: revoked_subject -``` +TTP is useful when reviewers need to know: -The demo is implemented in `examples/local-trust-gate-demo.mjs` and uses the routing engine in `packages/trust-routing-engine`. +| Question | TTP Contribution | +| --- | --- | +| Is this trust claim fresh enough? | Expiration and freshness requirements | +| Has trust decayed below the action threshold? | Time-aware trust decay evaluation | +| Who issued this trust, and for what scope? | Issuer, domain, scope, and evidence fields | +| Is delegated authority still bounded? | Delegation and authority context grammar | +| What result should a runtime authority system evaluate? | Structured trust context and evaluation output | --- ## What TTP Is -- A protocol for **runtime trust decisions**. -- A receipt and token model for **stateless verification at service boundaries**. -- A way to combine evidence from **multiple independent issuers**. -- A trust-routing model for selecting a valid authority path before execution. -- A portable foundation for agent, workflow, and service governance. - -## What TTP Is Not +TTP is: -- Not a replacement for OAuth/OIDC, IAM, SPIFFE, mTLS, ZTNA, or API gateways. -- Not a generic monitoring dashboard. -- Not a static policy-only system. -- Not a vendor-locked hosted service requirement. +- A portable trust expression protocol. +- A declarative language for trust claims, proof requirements, authority context, delegation, expiration, and decay. +- A grammar runtime authority systems can evaluate before autonomous execution. +- A foundation for interoperability between agent runtimes, NHI governance systems, policy engines, gateways, and audit surfaces. +- A protocol layer beneath BlockSiFr runtime authority products and reference implementations. --- -## Core Flow +## What TTP Is Not -```text -execution request -> route resolution -> authority decision -> execution receipt -> enforcement -``` +TTP is not: -Concrete flow: +- A replacement for IAM, OAuth, OIDC, SAML, SCIM, SPIFFE, PAM, OPA, Cedar, API gateways, SIEM, or SOAR. +- A complete governance product or control plane. +- A runtime enforcement gateway by itself. +- A blockchain-dependent system. +- Production-ready cryptographic infrastructure in the current MVP. +- A claim that trust can be made permanent, universal, or risk-free. -1. A subject requests a protected action. -2. Issuers provide signed behavioral evidence. -3. A Trust Authority or resolver evaluates route, score, freshness, scope, and policy. -4. The service receives a scoped decision. -5. Execution is permitted, denied, stepped up, throttled, or constrained. -6. An execution receipt records what happened and why. +Runtime enforcement belongs in systems such as RAP, Execution Exchange, and integrated gateways. TTP supplies the trust grammar those systems can evaluate. --- -## Core Concept - -- Trust is evaluated at execution time, not only at login time. -- Receipts are signed and verifiable. -- Tokens are short-lived and domain-scoped. -- Services verify tokens statelessly. -- Trust can decay and recover based on recent behavior. -- Multi-issuer evidence reduces single-observer bias. +## Core Concepts + +| Concept | Meaning | +| --- | --- | +| Subject | Actor whose trust is being evaluated, such as an agent, service account, workload, API, or pipeline. | +| Trust claim | A scoped statement that a subject has a trust score issued by a trust issuer. | +| Trust issuer | Entity that issues or attests to a trust claim. Issuers must be validated by the evaluator or runtime authority layer. | +| Trust score | Numeric signal, usually `0.0` to `1.0`, representing current trust for a specific scope. | +| Trust decay | Time-based reduction of effective trust after issuance. | +| Delegation | Bounded transfer of authority from one subject or issuer context to another. | +| Authority context | Action, resource, proof, and runtime context required before execution. | +| Proof | Requirement that a subject must satisfy, including threshold, freshness, issuer, and proof mode. | +| Attestation | Evidence from an issuer, runtime, gateway, or governance system supporting a trust claim. | +| Threshold | Required trust score for a proof or authority context. | +| Expiration | Time after which a trust claim or proof must fail. | +| Evaluation result | Structured output showing effective score, required score, result, reason, proof mode, and evaluation time. | --- -## How it works - -```text -Agent -> Issuers -> Trust Authority -> Trust Token -> Service Verifier -> Execution -``` - -Trust flow: - -1. Agent performs actions -1. Independent issuers observe behavior -1. Issuers generate signed behavioral receipts -1. Trust Authority aggregates receipts and computes trust score -1. Trust Authority issues short-lived trust token -1. Agent presents token to service -1. Service verifies token and enforces policy -1. Access granted or denied - -Verification at the service boundary is stateless and cryptographic. - ------ - -## Trust Routing Subsystem - -TTP includes a runtime **Trust Routing** subsystem for trust-before-execution: - -`execution request -> route resolution -> authority decision -> execution receipt -> enforcement` - -Core implementation entry points: -- `apps/trust-route-resolver/src/server.mjs` (runtime APIs) -- `packages/trust-routing-engine/src/*` (resolver, decay, policy, receipt logic) -- `.github/workflows/governed-execution.yml` (GitHub Actions governed execution example) -- `examples/local-trust-gate-demo.mjs` (local permit/step-up/deny demo) - ------ - -## Core Components - -### Behavioral Receipts - -Signed records of observed agent behavior. - -Receipts contain: - -- agent identity -- issuer identity -- event type -- timestamp -- domain -- behavioral score (optional) -- cryptographic signature - -Receipts are tamper-evident and verifiable. - ------ - -### Independent Issuers - -Issuers observe and attest to agent behavior. - -Examples: - -- API gateways -- Tool execution environments -- Inference gateways -- Security monitors -- Sandbox runtimes - -Multiple issuers reduce manipulation risk. - ------ - -### Trust Authority - -Aggregates receipts and issues trust tokens. - -Responsibilities: - -- Verify receipt signatures -- Aggregate behavioral evidence -- Compute trust score -- Issue short-lived trust tokens - -Trust Authorities may be: - -- Self-hosted -- Enterprise-hosted -- Provided as managed infrastructure - ------ - -### Trust Tokens - -Short-lived cryptographically signed tokens containing: - -- agent identity -- trust score -- domain scope -- issuance timestamp -- expiration timestamp - -Services verify tokens before granting access. - -Tokens expire quickly to ensure freshness. - ------ - -### Service Verifier - -Service-side verification logic. - -Verifies: - -- Token signature -- Token freshness -- Domain scope -- Minimum trust score - -Verification is stateless and fast. - ------ - -## Example Use Case: AI Retention Systems - -Autonomous retention agents perform actions such as: - -- Issuing discounts -- Triggering campaigns -- Sending customer messages - -Without TTP: - -Services trust agents based only on identity. - -With TTP: +## Simple Example -Services verify that the agent is currently trustworthy based on recent behavior. - -Flow: - -``` -Retention Agent → Trust Authority → Trust Token → Service → Verified Execution -``` - -This enables safe autonomous retention. - -See for detailed integration guide. - ------ - -## Protocol Properties - -### Runtime Trust Evaluation - -Trust is evaluated continuously, not just at authentication. - ------ - -### Behavioral Trust - -Trust derives from observed behavior, not static credentials. - ------ - -### Cryptographic Verification - -Trust decisions are based on signed, verifiable evidence. - ------ - -### Stateless Enforcement - -Services do not require access to behavioral history. - -Trust tokens contain necessary verification data. - ------ - -### Domain Isolation - -Trust is scoped to operational domains. - -Trust in one domain does not automatically transfer to another. - ------ - -### Issuer Independence - -Trust evidence may originate from multiple independent issuers. - ------ - -## Receipt Schema - -Canonical receipt structure: - -```json -{ - "ttp_version": "1.0", - "receipt_id": "uuid-v4", - "agent_id": "string", - "issuer_id": "string", - "event_type": "string", - "event_data": {}, - "domain": "string", - "timestamp": 1700000000000, - "score": 0.92, - "signature": "base64url-encoded-ed25519" +```ttp +subject "agent:invoice_reviewer" { + type = "ai_agent" + issuer = "blocksifr.local" + domain = "finance" } -``` - -Signatures use Ed25519. The `ttp_version` field enables verifiers to apply the correct validation rules as the protocol evolves. See [protocol/schemas/receipt.schema.json](protocol/schemas/receipt.schema.json) for the full JSON Schema. - ------ -## Trust Token Structure +trust "agent:invoice_reviewer" { + issuer = "verifiedtrust:tenant_123" + score = 0.86 + issued_at = "2026-05-11T12:00:00Z" + expires_at = "2026-05-11T18:00:00Z" -JWT format with TTP-specific claims: + decay { + model = "linear" + half_life = "6h" + minimum = 0.40 + } -```json -{ - "ttp_version": "1.0", - "sub": "agent_id", - "iss": "trust_authority_id", - "iat": 1700000000, - "exp": 1700000300, - "jti": "unique-token-id", - "ttp_domain": "retention", - "ttp_score": 0.91, - "ttp_issuer_count": 3, - "ttp_receipt_window": 300 + scope = [ + "invoice.read", + "invoice.recommend" + ] } -``` - -Key claims: - -- `ttp_version` — protocol version used to produce this token -- `ttp_score` — aggregated trust score (0.0–1.0) -- `ttp_issuer_count` — number of independent issuers contributing receipts -- `ttp_receipt_window` — seconds of behavioral history reflected in the score -- `jti` — unique token ID for replay detection - -Tokens are short-lived. Recommended maximum TTL is 300 seconds. See [protocol/schemas/trust-token.schema.json](protocol/schemas/trust-token.schema.json) for the full JSON Schema. - ------ - -## Reference Implementation - -Reference SDK provides: - -- Agent token retrieval -- Receipt submission -- Service verification middleware - -Example: -```typescript -import { TTPClient } from "@ttp/sdk" - -const client = new TTPClient({ - agentId: "agent-1", - privateKey: process.env.TTP_PRIVATE_KEY, - authority: "https://api.ttp.network" -}) - -const token = await client.getTrustToken({ - domain: "retention" -}) -``` +proof "invoice_review_threshold" { + subject = "agent:invoice_reviewer" + required_score = 0.75 + mode = "cleartext-dev" + freshness = "30m" +} -Service verification: - -```typescript -import { verifyTTPToken } from "@ttp/sdk" - -app.post("/api/issue-discount", async (req, res) => { - const token = req.headers["x-ttp-token"] - - const verification = await verifyTTPToken(token, { - domain: "retention", - minScore: 0.85 - }) - - if (!verification.valid) { - return res.status(403).json({ error: "Insufficient trust" }) - } - - // Execute action - await issueDiscount(req.body) - res.json({ success: true }) -}) +authority_context "invoice_review" { + action = "invoice.recommend" + resource = "invoice:*" + requires = proof.invoice_review_threshold +} ``` ------ - -## Quickstart (Simple Path) - -If you want the fastest path from zero to first protected action: - -1. **Run the Trust Authority** using the reference implementation. -1. **Register one agent + one issuer** using admin endpoints. -1. **Submit receipts** from your issuer as the agent performs actions. -1. **Request a trust token** from the agent. -1. **Verify token in your service** and enforce `minScore`. - -Use this guide for full commands and environment setup: -- [docs/integration-guide.md](docs/integration-guide.md) - ------ - -## Integration Paths (Choose One) - -### Path A — Agent builder -You own an autonomous agent and need runtime trust gating. - -- Integrate `TTPClient` in the agent runtime. -- Request domain-scoped trust tokens before sensitive actions. -- Pass `X-TTP-Token` to downstream protected services. - -### Path B — Service/API owner -You operate APIs and need behavior-aware authorization. +More examples are in [`examples/`](examples/). -- Add TTP middleware or manual token verification. -- Configure per-route `domain` and `minScore` policies. -- Enforce deny/degrade/cached fallback by operation risk. - -### Path C — Platform/security operator -You run shared infrastructure for many agents. - -- Deploy and operate the Trust Authority. -- Register issuers and agents. -- Define score thresholds, quarantine policies, and domain boundaries. - ------ - -## Build the Network (Core -> Edge Participation Model) - -TTP adoption works best when participants can join at different layers. You do **not** need to run everything on day one. - -### Role 1 — Network Core Operator -Owns shared trust infrastructure for a domain/ecosystem. - -- Stand up and operate a Trust Authority. -- Publish verification keys and operational policies. -- Curate issuer admission, diversity, and governance. - -### Role 2 — Issuer Operator -Contributes signed behavioral evidence. - -- Run one or more issuers (gateway, runtime, monitor, sandbox). -- Submit high-quality receipts with clear event semantics. -- Maintain independent operational control to reduce collusion risk. - -### Role 3 — Verifier / Service Owner -Enforces trust at execution boundaries. - -- Verify TTP tokens at API, tool, or workflow boundaries. -- Apply domain-specific `minScore` thresholds. -- Use fallback modes appropriate to business risk. - -### Role 4 — Agent Builder / Integrator -Makes autonomous systems TTP-aware. - -- Request short-lived trust tokens per domain. -- Present tokens to protected services. -- Tune behavior and controls using trust feedback loops. - -### Start where you are - -- If you're an enterprise platform team: start as **Network Core + Verifier**. -- If you're an infra/security vendor: start as **Issuer + Verifier**. -- If you're an agent framework/vendor: start as **Agent Builder + Issuer**. -- If you're a single product team: start as **Verifier**, then add issuer coverage. - -This core-to-edge model lets the network expand outward without forcing every team to adopt every component at once. - ------ - -## Agent Registry & Trust Operations (Reference API) - -The reference Trust Authority includes admin endpoints that act as an operator-facing registry for known agents and operational trust state. - -### Register known agents - -```bash -curl -X POST http://localhost:3000/v1/admin/agents \ - -H "Authorization: Bearer $ADMIN_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "agent_id": "agent-retention-001", - "description": "Retention agent for production" - }' -``` - -### Check agent status (active/quarantined/blocked) +--- -```bash -curl -X GET http://localhost:3000/v1/admin/agents/agent-retention-001/status \ - -H "Authorization: Bearer $ADMIN_KEY" -``` +## CLI Preview -### Quarantine or block when behavior degrades +The current CLI is an MVP reference scaffold. It performs basic parsing, validation, linear trust decay, expiration checks, threshold checks, and JSON output. ```bash -# Quarantine (temporary) -curl -X POST http://localhost:3000/v1/admin/agents/agent-retention-001/quarantine \ - -H "Authorization: Bearer $ADMIN_KEY" \ - -H "Content-Type: application/json" \ - -d '{"mode":"manual","reason":"investigating anomalous tool calls"}' - -# Block (hard stop) -curl -X POST http://localhost:3000/v1/admin/agents/agent-retention-001/block \ - -H "Authorization: Bearer $ADMIN_KEY" \ - -H "Content-Type: application/json" \ - -d '{"reason":"confirmed compromise"}' +npm run ttp -- check examples/01-basic-agent.ttp +npm run ttp -- eval examples/02-trust-decay.ttp --subject agent:invoice_reviewer --at now +npm run ttp -- version ``` -### Capture trust score and behavior metrics - -- Use `POST /v1/tokens` responses for **current trust score** and **issuer participation** (`score`, `issuer_count`). -- Use behavioral receipts as your event-level audit stream (`event_type`, `event_data`, `score`, `timestamp`). -- Build dashboards around score trend, issuer diversity, and domain-specific trust drift. - ------ - -## Repo Readiness Assessment (Intent, Onboarding, Integration) - -This repository is structured to support the intended platform model (open protocol + reference implementation + integration docs): - -- **Protocol clarity**: normative protocol and schemas under `protocol/`. -- **Integration docs**: architecture, security, and integration guidance under `docs/`. -- **Runnable reference stack**: trust authority and issuer reference implementations under `reference-implementations/`. -- **Practical examples**: starter integration examples under `examples/`. - -Recommended next documentation improvements for onboarding at scale: - -- Add an "operator runbook" with production SLOs, backup/restore, and incident workflows. -- Add a standard metrics spec for dashboards (score trend, quarantine rate, issuer coverage, replay rejects). -- Add a single-page "day-0 to day-30" rollout checklist for platform teams. - ------ - -## Where TTP Fits - -|System |Role |Relationship to TTP | -|---------------|---------------------|-----------------------------------------------------| -|OAuth / OIDC |Identity & authz |Complementary — OAuth says *who*, TTP says *trustworthy now* | -|IAM |Static permissions |Complementary — IAM grants access, TTP continuously earns it | -|API Gateway |Routing & rate limit |Integration point — gateway acts as an issuer | -|Service Mesh |Connectivity (mTLS) |Complementary — mesh verifies identity, TTP verifies behavior | -|SPIFFE / SPIRE |Workload identity |Complementary — SPIFFE issues SVIDs, TTP adds behavioral layer on top | -|Network Security Platforms (Zscaler, Palo Alto, Juniper) |Network/session controls|Complementary — network controls enforce transport/session policy; TTP enforces behavior-aware action trust | -|ZTNA |Network access |Complementary — ZTNA controls the network, TTP controls the action | -|AI Agent Frameworks | Execution |Integration point — LangChain, CrewAI agents become TTP-aware | - -TTP fills the gap between *authenticated* and *trustworthy*. It does not replace any layer in this stack — it adds the behavioral trust dimension that none of them provide. - ------ - -## Network-Level Agent Infrastructure (Zscaler, Palo Alto, Juniper) - -Short answer: -- **Is it possible?** Yes. -- **Is it in this repo today as first-party connectors?** Not yet. -- **Is it a valid deployment pattern happening in practice?** Yes — via standard integration seams (gateways, identity, logs, policy engines). - -Practical integration model: -1. Network/security platform observes session and policy events. -2. An issuer adapter converts those events into signed TTP receipts. -3. Trust Authority aggregates with other issuers (runtime, tool, API gateway). -4. Verifiers enforce action-level trust with TTP tokens at service boundaries. - -This preserves clear responsibility layers: -- Network stack decides connection/session posture. -- TTP decides whether a specific autonomous action should execute now. - -If you need vendor-specific blueprints, start with the issuer adapter pattern in the integration guide and implement per-vendor event mappers. - ------ - -## Security Model - -Uses: - -- Ed25519 signatures -- SHA-256 hashing -- Stateless verification -- Short-lived tokens - -Resistant to: - -- Token replay -- Signature forgery -- Tampering - ------ - -## Threat Model Considerations - -Known challenges: - -- Issuer collusion -- Behavioral manipulation -- Trust oscillation -- Observation gaps - -Mitigations include: - -- Issuer diversity -- Short token lifetime -- Domain isolation -- Multi-issuer requirements - -See for detailed threat analysis. - ------ - -## Performance Goals - -Designed for: - -- High-volume verification -- Low-latency execution -- Stateless service enforcement - -Verification requires only: +Expected JSON shape: -- Signature validation -- Token inspection - -No network calls required. - -Target latency: < 5ms for token verification. - ------ - -## Design Philosophy - -TTP is built with: - -- Minimal protocol surface -- Cryptographic trust guarantees -- Deployment flexibility -- Vendor neutrality -- Ecosystem openness - -TTP is infrastructure. - -## Trust Routing subsystem - -TTP includes Trust Routing for pre-execution authority-path resolution: - -```text -execution request -> route resolution -> authority decision -> execution receipt -> enforcement +```json +{ + "subject": "agent:invoice_reviewer", + "effective_score": 0.84, + "required_score": 0.75, + "result": "TRUST_PROOF_VALID", + "reason": "effective trust score meets threshold", + "proof_mode": "cleartext-dev", + "evaluated_at": "2026-05-11T12:30:00.000Z" +} ``` -Key implementation entry points: - -- `apps/trust-route-resolver/src/server.mjs` -- `packages/trust-routing-engine/src/*` -- `.github/workflows/governed-execution.yml` -- `examples/local-trust-gate-demo.mjs` - --- -## What guarantees you get - -- Cryptographic integrity of receipts and tokens. -- Time-bounded trust decisions. -- Domain isolation (trust does not automatically transfer across domains). -- Fail-closed decision model when trust requirements are not met. -- Stateless verification at service boundaries. +## BlockSiFr Stack Boundary -``` -ttp-protocol/ -├── protocol/ -│ ├── spec.md # Protocol specification -│ ├── schemas/ # JSON schemas -│ └── rfc/ # Protocol RFCs -├── sdk/ -│ └── typescript/ # TypeScript SDK foundation -├── examples/ -│ ├── local-trust-gate-demo.mjs -│ ├── retention-platform-integration.md -│ ├── basic-agent/ -│ ├── service-integration/ -│ └── issuer-implementation/ -├── docs/ -│ ├── architecture.md -│ ├── security.md -│ ├── governance.md -│ ├── patent-strategy.md -│ ├── integration-guide.md -│ ├── getting-started.md -│ ├── operator-guide.md -│ └── ecosystem-integrations.md -├── reference-implementations/ -│ ├── trust-authority/ -│ └── issuers/ -└── README.md -``` - ---- +TTP is the protocol foundation beneath the BlockSiFr stack. It should remain narrow and portable. -## What you run +| Layer | Responsibility | +| --- | --- | +| TTP | Trust expression, delegation, decay, proof semantics, authority context grammar. | +| SCIM-RE | Runtime execution resource model: `WorkloadIdentity`, `AuthorityGrant`, `Attestation`, `ExecutionRequest`, `ExecutionReceipt`. | +| RAP | Runtime Authority Protocol decision exchange: `PERMIT`, `STEP_UP`, `DENY`, `THROTTLE`, `ESCALATE`, `CONSTRAIN`. | +| Execution Exchange | Enforcement gateway, route, and runtime integration layer. | +| FrontDesk | Operator/customer UI, AI workforce command center, business approval, and evidence surface. | +| VerifiedTrust | Enterprise NHI posture, policy, lifecycle governance, and compliance control plane. | -Reference components in this repo: - -- Protocol + schemas: `protocol/` -- Trust Authority reference: `reference-implementations/trust-authority/` -- Issuer references: `reference-implementations/issuers/` -- Trust-route resolver demo: `apps/trust-route-resolver/` -- Trust-routing engine: `packages/trust-routing-engine/` +See [`docs/ttp-vs-rap-vs-scim-re.md`](docs/ttp-vs-rap-vs-scim-re.md). --- -## What you integrate - -Choose by role: - -### Agent/runtime team - -- Request domain-scoped trust tokens before sensitive actions. -- Pass token to protected downstream service. +## Current Implementation Status -### Service/API team - -- Verify token per route. -- Enforce domain and minimum score. - -### Platform/security team - -- Operate Trust Authority. -- Register issuers and agents. -- Set thresholds and governance policy. +| Area | Status | +| --- | --- | +| Protocol specification | Draft complete, still open for review | +| `.ttp` examples | Initial examples added | +| Parser | MVP parser scaffold | +| AST | Initial object model | +| Trust decay evaluator | Linear decay implemented for MVP examples | +| Proof engine | Cleartext-dev threshold evaluation | +| ZKP support | Future/advanced backend, not required for MVP | +| Runtime enforcement | Out of scope for TTP core; belongs in RAP/Execution Exchange integrations | --- -## Quickstart - -### 1) Run the local trust-gate demo +## MVP Scope -```bash -npm run demo -``` +The MVP focuses on a buildable, testable protocol kernel: -This shows `PERMIT`, `STEP_UP`, and `DENY` decisions with execution receipts. +- Parse `.ttp` files. +- Validate required `subject`, `trust`, `proof`, and `authority_context` blocks. +- Build an AST-like object model. +- Evaluate static trust score. +- Evaluate linear trust decay over time. +- Evaluate threshold conditions. +- Emit JSON evaluation results. +- Support `cleartext-dev` proof mode. -### 2) Run Trust Authority reference implementation +See [`MVP.md`](MVP.md). -```bash -cd reference-implementations/trust-authority -npm install -npm run build -npm run generate-keys -npm start -``` - ------ +--- ## Roadmap -**Phase 1: Foundation (Current)** - -- Protocol specification v1.0 -- TypeScript SDK -- Reference Trust Authority -- Retention platform integration examples - -**Phase 2: Ecosystem** - -- Python and Go SDKs -- Issuer reference implementations (API Gateway, Lambda, Kubernetes) -- Hosted Trust Authority beta -- Integration with major agent frameworks - -**Phase 3: Enterprise** - -- Enterprise Trust Authority features (audit, compliance, multi-tenant) -- Advanced threat detection -- Performance optimizations -- Governance framework maturity - -**Phase 4: Standardization** - -- Formal specification submission -- Multi-vendor implementations -- Industry adoption - -See for detailed timeline. - ------ - -## Contributing - -Contributions welcome. - -Areas of interest: - -- Trust Authority / network core operations -- Issuer integrations and adapters -- Verifier enforcement patterns -- Agent SDK/runtime integrations -- Security analysis and threat modeling -- Documentation and onboarding +| Phase | Focus | +| --- | --- | +| Phase 0 | Protocol cleanup, examples, threat model, stack boundaries | +| Phase 1 | MVP parser/evaluator, AST, decay evaluator, JSON output | +| Phase 2 | RAP request mapping, SCIM-RE resource mapping, SDK | +| Phase 3 | Signed claims, issuer registry, replay protection, ZKP backend prototype | +| Phase 4 | VSCode extension, formatter, conformance tests, reference gateway integration | -See for guidelines. - ------ - -## Community - -- **Discussions:** [GitHub Discussions](https://github.com/blocksifrdev/ttp-protocol/discussions) -- **Issues:** [GitHub Issues](https://github.com/blocksifrdev/ttp-protocol/issues) -- **Email:** hello@blocksifr.com -- **Twitter:** [@blocksifr](https://twitter.com/blocksifr) - ------ - -## Integration References - -- Easy connect API: `docs/easy-connect-api.md` -- Runtime connect contract: `runtime/api/connect.contract.md` -- Full verification flow: `docs/integration-guide.md` +See [`ROADMAP.md`](ROADMAP.md). --- -## GitHub self-governance (runtime authority for repo actions) - -- Architecture: `docs/github-self-governance-reference-architecture.md` -- Protected action model: `docs/protected-action-model.md` -- Workflow contract: `docs/protected-gate-workflow-contract.md` - ---- - -## Security, governance, and release readiness +## Security Model -- Security model: `docs/security.md` -- Security policy: `SECURITY.md` -- Contributing: `CONTRIBUTING.md` -- Public readiness checklist: `docs/public-readiness.md` -- Open-source boundary: `docs/open-source-boundary.md` -- Repo access control: `docs/repo-access-control.md` +TTP assumes trust is scoped, temporary, issuer-bound, and evaluated at execution time. Trust claims must expire. Proof freshness matters. Issuers must be validated. Runtime enforcement must fail closed when trust context cannot be evaluated. ---- +TTP alone does not enforce execution. Enforcement happens through RAP, Execution Exchange, FrontDesk-integrated gateways, or equivalent runtime controls. -## Related systems (complementary) +Read: -- OAuth/OIDC, IAM: identity and static authorization. -- SPIFFE/SPIRE, mTLS: workload identity/channel security. -- ZTNA: network access posture. -- API gateways/service mesh: traffic and connectivity controls. - -TTP adds execution-time behavioral trust decisions on top of these layers. +- [`THREAT_MODEL.md`](THREAT_MODEL.md) +- [`SECURITY.md`](SECURITY.md) +- [`docs/protocol-security-model.md`](docs/protocol-security-model.md) --- -## Project status +## Contributing -- Spec: `v1.0` (active development) -- TypeScript SDK: present -- Python/Go SDKs: planned +Contributions are welcome when they improve protocol clarity, implementation correctness, examples, tests, security review, or interoperability. -See `docs/roadmap.md`. +Start with [`CONTRIBUTING.md`](CONTRIBUTING.md) and [`GOVERNANCE.md`](GOVERNANCE.md). --- ## License -Apache License 2.0. See `LICENSE`. - -*Building the trust layer for autonomous systems.* +TTP is licensed under the [Apache License 2.0](LICENSE). diff --git a/ROADMAP.md b/ROADMAP.md index 88d403f..271f058 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,80 +1,57 @@ -TTP Roadmap - -Current Stage - -Specification-first, implementation-seeding phase. - -The protocol core is stabilizing while reference implementations mature. -Primary objectives are interoperability validation, ecosystem signaling, and developer accessibility. - -⸻ - -Next 30 Days - -Protocol - • Finalize token claim set - • Finalize receipt structure - • Finalize issuer responsibility model - • Establish versioning policy for spec evolution - -Implementations - • Harden Go verifier reference implementation - • Release minimal issuer reference service - • Baseline aggregation reference logic - • Introduce interoperability test fixtures - -SDK - • Stabilize Python SDK interface - • Achieve feature parity for JavaScript SDK - • Implement token auto-refresh lifecycle handling - -Documentation - • Publish architecture diagrams - • Expand threat model documentation - • Release deployment guide (single-node reference) - • Improve contributor onboarding materials - -⸻ - -Next 60 Days - • Release Rust SDK (developer ecosystem expansion) - • Introduce CLI tooling - • ttp verify - • ttp issue - • Production-grade LangChain integration - • Gateway middleware packages - • Publish empirical performance benchmarks - • Begin issuer certification framework draft - -⸻ - -Next 90 Days - • Multi-issuer simulation environment - • Adversarial testing harness - • High-availability verifier deployment model - • Hosted reference issuer infrastructure - • Aggregation model exploration draft - • Independent implementation outreach - -⸻ - -Long-Term Direction - • Multiple independent protocol implementations - • Formal specification standardization pathway - • Academic research collaboration - • Production adoption case studies - • Ecosystem issuer diversity growth - • Governance model evolution - • Cross-organization trust federation pilots - -⸻ - -Roadmap Philosophy - -This roadmap prioritizes: - • protocol stability before expansion - • ecosystem participation over feature breadth - • reference interoperability over vendor lock-in - • measured evolution over premature formalization - -Milestones are directional rather than rigid commitments and will adapt as community and deployment feedback emerge. \ No newline at end of file +# TTP Roadmap + +TTP is in a specification-first, implementation-seeding phase. The immediate objective is a credible protocol kernel: clear grammar, runnable examples, testable evaluation semantics, and explicit boundaries with runtime enforcement systems. + +## Phase 0 - Protocol Cleanup + +- Rewrite README positioning and scope. +- Publish core specification. +- Add `.ttp` examples. +- Add threat model and security policy. +- Clarify TTP, SCIM-RE, RAP, Execution Exchange, FrontDesk, and VerifiedTrust boundaries. +- Remove language that implies production readiness or complete governance coverage. + +## Phase 1 - MVP Parser/Evaluator + +- Parse core blocks: `subject`, `trust`, `proof`, `authority_context`, `delegation`. +- Build an AST/object model. +- Validate required syntax and useful errors. +- Evaluate static trust scores. +- Evaluate trust decay over time. +- Evaluate threshold conditions. +- Emit JSON evaluation results. +- Add fixture and CLI tests. + +## Phase 2 - Runtime Integration + +- Map TTP evaluation context into RAP requests. +- Map TTP subject and attestation fields into SCIM-RE resources. +- Add an `ExecutionReceipt` placeholder mapping. +- Publish a small SDK for embedding the evaluator. +- Provide integration examples for CI, API gateways, MCP tool gateways, and agent runtimes. + +## Phase 3 - Proof Hardening + +- Add signed trust claims. +- Define issuer registry and issuer validation rules. +- Add replay protection guidance. +- Add receipt hash semantics. +- Prototype a ZKP-compatible proof backend. +- Keep `cleartext-dev` as the non-production development mode. + +## Phase 4 - Ecosystem + +- Add VSCode language support. +- Add formatter and linter. +- Publish conformance tests. +- Define policy registry conventions. +- Build reference gateway integration. +- Encourage independent implementations. + +## Roadmap Principles + +- Protocol clarity before feature breadth. +- Narrow TTP scope; no blurred product-layer claims. +- Security review before production recommendations. +- Interoperability over vendor lock-in. +- Concrete examples and tests over manifesto language. diff --git a/SECURITY.md b/SECURITY.md index 2c5d717..7287ee0 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,61 +1,66 @@ # Security Policy -This repository contains security-sensitive trust protocol and reference implementation code. +TTP is security-sensitive protocol work. The current repository contains a draft specification, examples, and a reference implementation scaffold. It is not recommended for production enforcement. -## Supported Scope +## Supported Versions -Security reports are accepted for: -- protocol semantics and verification logic -- reference Trust Authority, issuer, and verifier code -- cryptographic handling, token validation, and replay protections -- admin/authz controls in reference APIs +| Version / Branch | Security Support | +| --- | --- | +| `main` | Best-effort security review during active development | +| Released packages | Not yet available | +| Pre-MVP examples | Documentation and test fixture support only | -## Reporting a Vulnerability +## Reporting Vulnerabilities -Please **do not** open public GitHub issues for vulnerabilities. +Please do not open public GitHub issues for vulnerabilities. Report privately to: **maurice@blocksifr.com** Include: -1. affected component/path -2. reproduction steps / proof of concept -3. impact and exploit conditions -4. suggested mitigation (if available) - -We aim to acknowledge reports within 48 hours. - -## Repository Access Controls (Pre-Public Invite) - -Before inviting external users/collaborators: - -1. Enforce least privilege: - - default role: Read - - Write/Maintain only for trusted maintainers - - Admin restricted to core owners -2. Require branch protection on default branch: - - PR required (no direct pushes) - - required review approvals - - required status checks - - dismiss stale approvals on new commits -3. Require CODEOWNERS review for protocol/security-critical paths. -4. Require 2FA for org members and outside collaborators. -5. Protect secrets: - - enable secret scanning + push protection - - no long-lived credentials in repo - - rotate keys on any suspicion of exposure -6. Protect release integrity: - - tag protection - - signed release artifacts where possible - -## Safe External Collaboration Model - -- Use issue templates and scoped labels for newcomer tasks. -- Keep security-sensitive discussions private until patched. -- Prefer small, auditable PRs for protocol or authz changes. -- Require explicit security review for changes touching trust semantics. - -## Additional References - -- Security model: `docs/security.md` -- Public release checklist: `docs/public-readiness.md` -- Repo access model: `docs/repo-access-control.md` + +- Affected component or path. +- Reproduction steps or proof of concept. +- Expected and actual behavior. +- Security impact and exploit conditions. +- Suggested mitigation, if available. + +We aim to acknowledge reports within 48 hours and coordinate remediation before public disclosure. + +## Security Expectations + +Contributors should assume adversarial inputs and hostile runtime environments. Changes that affect parsing, trust scoring, expiration, issuer handling, proof modes, delegation, receipt handling, or runtime integration require extra review. + +Security-sensitive changes should include tests for failure paths, malformed input, expired trust, insufficient thresholds, and unsafe defaults. + +## Cryptographic Caution + +The MVP uses `cleartext-dev` proof evaluation. This mode is intended for local development, examples, and protocol review only. + +Do not treat the current implementation as a cryptographic verifier. Signed claims, issuer registries, replay protection, key rotation, secure time, and advanced proof backends are future hardening work. + +ZKP support is an advanced verification backend and is not required for the MVP. + +## Production Readiness Disclaimer + +TTP currently provides draft protocol semantics and a reference implementation in active development. It does not provide production-grade enforcement by itself. + +Runtime enforcement must be implemented by RAP, Execution Exchange, FrontDesk-integrated gateways, API gateways, CI gates, or equivalent systems that fail closed when trust cannot be evaluated. + +## Responsible Disclosure Process + +1. Reporter submits a private report. +2. Maintainers acknowledge receipt. +3. Maintainers reproduce and classify impact. +4. A fix or mitigation is prepared privately. +5. Reporter validates where practical. +6. Public disclosure is coordinated after remediation. + +## Out of Scope for the Current MVP + +- Production ZKP verification. +- Distributed trust federation. +- Blockchain anchoring. +- Enterprise-grade issuer registry operation. +- Hosted governance control plane behavior. +- Full FrontDesk, VerifiedTrust, RAP, or Execution Exchange enforcement logic. +- Vulnerabilities in downstream deployments that modify or bypass the reference evaluator. diff --git a/SPECIFICATION.md b/SPECIFICATION.md new file mode 100644 index 0000000..a8b94b1 --- /dev/null +++ b/SPECIFICATION.md @@ -0,0 +1,267 @@ +# Trust Transfer Protocol Specification + +**Status:** Draft +**Current milestone:** MVP parser + trust decay evaluator +**Production use:** Not recommended +**License:** Apache 2.0 + +## Protocol Purpose + +Trust Transfer Protocol (TTP) is an open protocol and declarative language for expressing verifiable trust, authority context, delegation, and decay before autonomous systems execute. + +TTP answers: + +> Can this actor prove enough current trust to attempt this action now? + +TTP does not enforce actions by itself. It produces trust context and evaluation results that runtime systems such as RAP, Execution Exchange, API gateways, CI gates, and FrontDesk-integrated control surfaces can use before execution. + +## Design Principles + +- **Narrow scope:** TTP expresses trust context; it is not a complete governance product. +- **Execution-time evaluation:** Trust must be evaluated near the time of action. +- **Scoped trust:** Trust claims must apply to explicit subjects, domains, scopes, and resources. +- **Freshness:** Trust claims must expire and proofs may require tighter freshness windows. +- **Decay:** Trust is not permanent. Effective trust may decline over time. +- **Issuer accountability:** Trust claims must identify the issuer. +- **Proof portability:** The grammar must support cleartext development mode and future signed or zero-knowledge proof backends. +- **Fail-closed integration:** Runtime enforcement layers must reject execution when trust context cannot be evaluated. + +## Syntax Model + +The draft `.ttp` syntax is block-oriented: + +```ttp +subject "agent:invoice_reviewer" { + type = "ai_agent" + issuer = "blocksifr.local" + domain = "finance" +} + +trust "agent:invoice_reviewer" { + issuer = "verifiedtrust:tenant_123" + score = 0.86 + issued_at = "2026-05-11T12:00:00Z" + expires_at = "2026-05-11T18:00:00Z" + + decay { + model = "linear" + half_life = "6h" + minimum = 0.40 + } + + scope = [ + "invoice.read", + "invoice.recommend" + ] +} + +proof "invoice_review_threshold" { + subject = "agent:invoice_reviewer" + required_score = 0.75 + mode = "cleartext-dev" + freshness = "30m" +} + +authority_context "invoice_review" { + action = "invoice.recommend" + resource = "invoice:*" + requires = proof.invoice_review_threshold +} +``` + +Blocks in the MVP: + +| Block | Purpose | +| --- | --- | +| `subject` | Defines the actor whose trust is evaluated. | +| `trust` | Defines issuer, score, lifetime, decay, scope, and evidence. | +| `proof` | Defines required score, proof mode, freshness, and subject. | +| `authority_context` | Defines action/resource context requiring a proof. | +| `delegation` | Defines bounded transfer of trust or authority context. | + +## Trust Object Model + +### Subject + +- `id`: Stable subject identifier. +- `type`: Actor type, such as `ai_agent`, `workload`, `service_account`, `pipeline`, or `api`. +- `issuer`: Entity that introduced or registered the subject. +- `domain`: Operational trust domain. +- `metadata`: Optional structured metadata. + +### TrustClaim + +- `subject`: Subject identifier. +- `issuer`: Trust issuer. +- `score`: Numeric trust score, typically `0.0` to `1.0`. +- `issued_at`: Claim issuance time. +- `expires_at`: Claim expiration time. +- `decay`: Decay configuration. +- `scope`: List of scoped capabilities. +- `evidence`: Optional attestations, receipt hashes, or external references. + +### TrustPolicy + +- `required_score`: Minimum effective score. +- `allowed_issuers`: Issuers accepted for the proof. +- `required_freshness`: Maximum age of claim or proof. +- `constraints`: Additional context constraints. +- `proof_mode`: Proof backend, such as `cleartext-dev`, `signed-claim`, or future `zkp`. + +### EvaluationResult + +- `subject`: Evaluated subject identifier. +- `effective_score`: Score after decay and validity checks. +- `required_score`: Required threshold. +- `result`: Evaluation outcome. +- `reason`: Human-readable reason. +- `expires_at`: Expiration time of the governing claim. +- `proof_mode`: Proof backend used. +- `receipt_hash_optional`: Optional receipt hash or external evidence reference. + +## Evaluation Model + +An evaluator SHOULD: + +1. Parse the `.ttp` document. +2. Validate required blocks and references. +3. Select the requested subject. +4. Locate a trust claim for that subject. +5. Check claim expiration. +6. Check proof freshness. +7. Apply trust decay. +8. Compare effective score to the proof threshold. +9. Return an `EvaluationResult`. + +Outcomes: + +| Result | Meaning | +| --- | --- | +| `TRUST_PROOF_VALID` | Effective score meets or exceeds threshold. | +| `TRUST_PROOF_INSUFFICIENT` | Effective score is below threshold. | +| `TRUST_PROOF_EXPIRED` | Claim or proof is expired. | +| `TRUST_PROOF_INVALID` | Syntax, reference, issuer, or proof validation failed. | + +## Trust Decay Model + +The MVP supports linear decay: + +```ttp +decay { + model = "linear" + half_life = "6h" + minimum = 0.40 +} +``` + +For MVP evaluation: + +- `score` starts at the claim score at `issued_at`. +- One `half_life` reduces the score by 50 percent of its distance from `minimum`. +- Effective score MUST NOT fall below `minimum` before expiration. +- Expired claims fail even if their minimum remains above threshold. + +Future versions may define exponential, stepped, risk-event, and issuer-specific decay. + +## Proof Model + +Proof mode declares how the evaluator verifies a trust statement. + +| Mode | Status | Meaning | +| --- | --- | --- | +| `cleartext-dev` | MVP | Development mode using explicit scores and timestamps in the `.ttp` file. | +| `signed-claim` | Future | Trust claim is signed by an issuer and verified by key registry. | +| `zkp` | Future | Zero-knowledge proof backend for selective disclosure. | + +The first implementation may use `cleartext-dev` proof evaluation. ZKP support is future/advanced and must not be presented as an MVP requirement. + +## Delegation Model + +Delegation expresses bounded trust transfer: + +```ttp +delegation "review_to_payment_exception" { + from = "agent:invoice_reviewer" + to = "agent:payment_exception_reviewer" + issuer = "verifiedtrust:tenant_123" + scope = ["invoice.exception.review"] + max_score = 0.72 + expires_at = "2026-05-11T16:00:00Z" +} +``` + +Delegation MUST be: + +- Explicit. +- Scoped. +- Time bounded. +- Issuer-bound. +- No stronger than the originating trust context unless policy explicitly allows otherwise. + +## Expiration and Freshness Model + +TTP distinguishes expiration from freshness. + +- `expires_at` defines when the trust claim must fail. +- `freshness` defines the maximum acceptable age for a proof or claim relative to evaluation time. + +Example: a claim may expire in six hours, but a high-risk action may require proof freshness of 30 minutes. + +## Output Model + +MVP JSON output: + +```json +{ + "subject": "agent:invoice_reviewer", + "effective_score": 0.84, + "required_score": 0.75, + "result": "TRUST_PROOF_VALID", + "reason": "effective trust score meets threshold", + "proof_mode": "cleartext-dev", + "evaluated_at": "2026-05-11T12:30:00.000Z", + "expires_at": "2026-05-11T18:00:00.000Z", + "receipt_hash_optional": null +} +``` + +## Error Model + +Errors SHOULD be structured and useful: + +| Code | Meaning | +| --- | --- | +| `FILE_NOT_FOUND` | Input file cannot be read. | +| `SYNTAX_ERROR` | `.ttp` syntax cannot be parsed. | +| `MISSING_SUBJECT` | No subject block exists or requested subject is absent. | +| `MISSING_TRUST` | No trust claim exists for the subject. | +| `MISSING_PROOF` | Required proof is absent. | +| `INVALID_REFERENCE` | A block references an unknown proof or subject. | +| `EXPIRED_TRUST` | Trust claim expired before evaluation. | +| `UNSUPPORTED_DECAY_MODEL` | Evaluator does not support the configured decay model. | +| `UNSUPPORTED_PROOF_MODE` | Evaluator does not support the proof mode. | + +## Security Considerations + +- TTP does not authenticate subjects by itself. +- TTP does not enforce runtime decisions by itself. +- Runtime enforcement must fail closed. +- Issuers must be validated before their claims are accepted. +- Clocks must be trustworthy enough for expiration and freshness checks. +- Overbroad delegation can create unsafe authority paths. +- `cleartext-dev` is not a production proof mode. +- Future signed and ZKP modes require careful key, nonce, replay, and issuer registry design. + +See [`THREAT_MODEL.md`](THREAT_MODEL.md) and [`docs/protocol-security-model.md`](docs/protocol-security-model.md). + +## Versioning + +TTP uses semantic versioning for implementation packages and explicit protocol versions for grammar compatibility. + +Draft files SHOULD declare a version once the grammar stabilizes: + +```ttp +ttp_version = "0.1" +``` + +Backward-incompatible grammar changes require a protocol version change and migration notes. diff --git a/THREAT_MODEL.md b/THREAT_MODEL.md new file mode 100644 index 0000000..9dd9f9b --- /dev/null +++ b/THREAT_MODEL.md @@ -0,0 +1,27 @@ +# TTP Threat Model + +TTP expresses trust context. TTP alone does not enforce execution. Enforcement happens through RAP, Execution Exchange, FrontDesk-integrated gateways, API gateways, CI gates, or equivalent runtime controls. + +| Threat | Description | Impact | Mitigation | MVP Status | Future Hardening | +| --- | --- | --- | --- | --- | --- | +| Forged trust claims | Attacker creates a fake trust claim or edits score/timestamps. | Unauthorized action may appear trusted. | Validate issuers, signatures, schema, and immutable evidence references. | Cleartext-dev only; not production safe. | Signed claims, issuer registry, canonical signing, key rotation. | +| Stale trust proofs | Old proof is reused after trust context has changed. | Actions proceed on outdated trust. | Expiration, freshness windows, short TTLs. | Expiration and freshness semantics documented; basic checks implemented. | Nonces, replay caches, runtime receipts. | +| Replay attacks | Previously valid proof or receipt is replayed. | Unauthorized repeated execution. | Bind proof to action, resource, time, and nonce. | Out of MVP. | Nonce registry, receipt hash binding, RAP request binding. | +| Issuer compromise | Valid issuer signs false claims. | Trust model can be corrupted. | Least privilege issuers, issuer reputation, revocation, independent issuers. | Documented risk. | Issuer registry, quorum rules, revocation feeds. | +| Malicious agent self-attestation | Agent issues trust about itself. | Inflated trust. | Disallow self-attestation unless explicitly marked and low weight. | Not enforced beyond examples. | Issuer policy constraints and signed issuer metadata. | +| Trust farming | Actor performs low-risk behavior to build trust for high-risk actions. | Inappropriate trust transfer. | Scope trust by action/domain/resource; use high-risk thresholds. | Scope syntax exists. | Risk-weighted decay, action-specific scoring. | +| Sybil attacks | Many fake subjects or issuers inflate trust. | Trust graph manipulation. | Issuer validation, subject registration, governance controls. | Out of MVP. | Identity binding, issuer reputation, abuse detection. | +| Proof expiration bypass | Runtime ignores expiration or clock is wrong. | Expired trust accepted. | Fail closed, reliable clocks, skew limits. | Expiration checks implemented in reference CLI. | Secure time, signed timestamps, RAP enforcement tests. | +| Policy downgrade attacks | Lower proof mode or lower threshold is substituted. | Weaker evaluation than intended. | Pin proof requirements in authority context and runtime policy. | Basic proof references parsed. | Policy signatures and version pinning. | +| Cross-domain trust abuse | Trust from one domain is reused in another. | Scope escape. | Domain and scope checks. | Domain captured; limited enforcement. | Domain-specific issuer policies and RAP mapping. | +| Runtime gate bypass | Actor calls target system without RAP or gateway enforcement. | TTP evaluation is skipped. | Place enforcement at mandatory control points. | Out of TTP core. | Execution Exchange, service mesh, CI and API gateway adapters. | +| Receipt tampering | Evidence or receipt is modified after creation. | Audit and proof integrity loss. | Sign receipts and hash evidence references. | Output supports optional receipt hash. | Canonical receipt schema and transparency log support. | +| Clock manipulation | Actor or runtime shifts time to avoid decay or expiration. | Trust remains valid too long or decays incorrectly. | Trusted server-side evaluation time and skew limits. | CLI uses evaluator time input. | Secure time source and signed evaluation receipts. | +| Misconfigured trust thresholds | Thresholds are too low or too broad. | Weak authority control. | Defaults, linting, review, risk-tier guidance. | Examples use explicit thresholds. | Policy linter and conformance tests. | +| Overbroad delegation | Delegation transfers too much authority or lasts too long. | Privilege expansion. | Bound delegation by scope, max score, issuer, expiration. | Delegation syntax example only. | Delegation evaluator and cycle detection. | +| Trust issuer impersonation | Attacker claims to be a trusted issuer. | Fake claims accepted. | Issuer identity verification and signature checks. | Out of MVP proof mode. | Issuer registry, JWKS/DID/PKI integrations. | +| Dependency compromise | Parser or runtime dependency is compromised. | Supply-chain compromise. | Minimal dependencies, lockfiles, CI checks. | CLI uses only Node standard library. | SLSA provenance, signed releases, dependency scanning. | + +## Security Boundary + +TTP is a protocol and language for trust expression. It must be integrated with runtime enforcement to have security effect. If a system can bypass the RAP or gateway decision point, TTP cannot prevent execution. diff --git a/docs/architecture.md b/docs/architecture.md index 17a0d36..b1b133a 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -1,301 +1,107 @@ -# TTP Architecture Guide +# TTP Architecture -This document describes the architecture of a TTP deployment: how components fit together, deployment topologies, and design decisions. +TTP is the protocol layer for trust expression before autonomous execution. It is intentionally narrower than the runtime systems that enforce authority decisions. ---- +## MVP Pipeline -## Component Overview - -``` -┌─────────────────────────────────────────────────────────────────────────────────┐ -│ TTP DEPLOYMENT │ -│ │ -│ ┌──────────────┐ actions ┌──────────────────────────────────────────┐ │ -│ │ │ ─────────────► │ ISSUERS │ │ -│ │ AGENT │ │ ┌──────────────┐ ┌──────────────────┐ │ │ -│ │ │ │ │ API Gateway │ │ Inference Monitor│ │ │ -│ │ (autonomous │ │ │ Issuer │ │ Issuer │ │ │ -│ │ system) │ │ └──────┬───────┘ └────────┬─────────┘ │ │ -│ │ │ │ │ │ │ │ -│ └──────┬───────┘ │ ┌──────┴───────┐ │ │ │ -│ │ │ │ Tool Runtime │ │ │ │ -│ │ request token │ │ Issuer │ │ │ │ -│ │ │ └──────┬───────┘ │ │ │ -│ ▼ └─────────┼───────────────────┼────────────┘ │ -│ ┌──────────────────┐ │ signed receipts │ │ -│ │ │ ◄──────────────────────┘───────────────────┘ │ -│ │ TRUST AUTHORITY │ │ -│ │ │ issues short-lived │ -│ │ • verifies │ signed JWT token │ -│ │ signatures │ ────────────────────────────────────────────► │ -│ │ • deduplicates │ │ │ -│ │ • aggregates │ │ │ -│ │ • signs tokens │ │ │ -│ └──────────────────┘ agent presents │ -│ token to service │ -│ │ │ -│ ▼ │ -│ ┌──────────────────┐ │ -│ │ VERIFIER │ │ -│ │ (inside service)│ │ -│ │ │ │ -│ │ • validate sig │ │ -│ │ • check expiry │ │ -│ │ • check domain │ │ -│ │ • check score │ │ -│ └──────────────────┘ │ -└─────────────────────────────────────────────────────────────────────────────────┘ +```text +.ttp file + | + parser + | + AST + | + validator + | + trust decay evaluator + | + proof evaluator + | + evaluation result JSON + | + RAP / SCIM-RE / FrontDesk integration ``` ---- - -## Data Flows +## Protocol Layer -### Flow 1: Receipt Generation (Continuous) +The protocol layer defines the grammar and object model: -Issuers run continuously, generating receipts as they observe agent behavior. - -``` -1. Agent performs an action (API call, tool execution, etc.) -2. Issuer observes the action and its outcome -3. Issuer computes a behavioral score for this event -4. Issuer creates a receipt with: agent_id, event_type, score, timestamp, domain -5. Issuer signs the receipt with its Ed25519 private key -6. Issuer POSTs the receipt to Trust Authority: POST /v1/receipts -7. Trust Authority verifies signature, deduplicates, stores receipt -``` +- Subjects. +- Trust claims. +- Proof requirements. +- Trust decay. +- Delegation. +- Authority context. +- Evaluation result shape. -Receipts are submitted **asynchronously** — the issuer does not block the agent's action waiting for TA acknowledgment. +This layer should remain portable and implementation-neutral. -### Flow 2: Token Issuance (On Demand) +## Parser -Agents request tokens when they need to call a protected service. +The parser reads `.ttp` files and produces a structured object model. The MVP parser supports block-oriented syntax for `subject`, `trust`, `proof`, `authority_context`, and `delegation`. -``` -1. Agent determines it needs to call a service protected by TTP domain "retention" -2. Agent checks its local token cache — no valid cached token exists -3. Agent POSTs to Trust Authority: POST /v1/tokens { agent_id, domain } -4. Trust Authority loads receipts for agent in domain within receipt_window -5. Trust Authority runs aggregation algorithm → trust_score -6. Trust Authority signs a JWT: { sub: agent_id, ttp_score, ttp_domain, exp: now+300 } -7. Trust Authority returns the signed JWT to the agent -8. Agent caches the token until near expiry -``` +Future parser work should add formal grammar tests, better diagnostics, formatting, and conformance fixtures. -### Flow 3: Token Verification (Per Request) +## AST -Every request to a TTP-protected service triggers verification. +The AST represents: -``` -1. Agent calls service with X-TTP-Token: -2. Verifier middleware intercepts the request -3. Verifier checks its local public key cache for the key matching jwt.header.kid -4. Verifier validates JWT signature -5. Verifier checks exp > now (with ≤30s clock skew) -6. Verifier checks ttp_domain == "retention" -7. Verifier checks ttp_score >= configured_threshold (e.g., 0.85) -8. If all checks pass: forward request to service handler -9. If any check fails: return 403 with error details -``` +- Subject definitions. +- Trust claims indexed by subject. +- Proof definitions indexed by proof name. +- Authority contexts referencing proofs. +- Delegations with bounded scope and expiration. -No network call is made in step 3-9. The public key is cached locally. +## Evaluator ---- +The evaluator applies: -## Deployment Topologies +- Subject lookup. +- Trust claim selection. +- Expiration checks. +- Freshness checks. +- Decay calculation. +- Threshold comparison. +- Result construction. -### Topology 1: Single-Tenant, Self-Hosted +The evaluator does not decide runtime enforcement actions such as `PERMIT` or `DENY`. Those are RAP concerns. -Suitable for enterprises running their own AI agent infrastructure. +## Decay Engine -``` -┌─────────────────────────── Enterprise Network ──────────────────────────┐ -│ │ -│ ┌─────────┐ ┌──────────────────────┐ ┌────────────────────┐ │ -│ │ Agent │────►│ Trust Authority │────►│ Internal APIs │ │ -│ │ Fleet │ │ (self-hosted) │ │ (with Verifier │ │ -│ └─────────┘ │ │ │ middleware) │ │ -│ │ • single tenant │ └────────────────────┘ │ -│ ┌─────────┐ │ • enterprise HSM │ │ -│ │ Issuers │────►│ for key storage │ │ -│ │(gateway,│ │ • audit logging │ │ -│ │monitor) │ └──────────────────────┘ │ -└─────────────────────────────────────────────────────────────────────────┘ -``` +The MVP supports linear decay. It computes an effective score at evaluation time and enforces a configured minimum before expiration. -**Pros:** Full control, data residency, no external dependencies. -**Cons:** Operational burden, requires internal expertise. - -### Topology 2: Managed Trust Authority - -Use BlockSiFr's hosted Trust Authority or a third-party managed service. - -``` -Enterprise: Cloud (Managed TA): -┌─────────────────────┐ ┌─────────────────────────┐ -│ ┌─────────────┐ │ │ │ -│ │ Agents │────┼──────────►│ Trust Authority │ -│ └─────────────┘ │ │ (managed service) │ -│ │ │ │ -│ ┌─────────────┐ │ │ • HA deployment │ -│ │ Issuers │────┼──────────►│ • HSM key storage │ -│ └─────────────┘ │ │ • SLA-backed │ -│ │ │ • audit + compliance │ -│ ┌─────────────┐ │ └─────────────────────────┘ -│ │ Services │ │ -│ │ (Verifiers) │ │ -│ └─────────────┘ │ -└─────────────────────┘ -``` - -**Pros:** No operational burden for Trust Authority, managed SLA. -**Cons:** External dependency, data sent to third party. - -### Topology 3: Federated Trust Authorities - -Multiple Trust Authorities operated by different organizations, with cross-authority trust federation (future protocol feature). - -``` -Organization A Organization B -┌──────────────────┐ ┌──────────────────┐ -│ Trust Authority │◄────────────►│ Trust Authority │ -│ (A) │ federation │ (B) │ -│ │ protocol │ │ -│ Agents in A │ │ Agents in B │ -└──────────────────┘ └──────────────────┘ -``` +Future engines may support exponential decay, event-driven decay, issuer-weighted decay, and risk-tier-specific decay. -**Use case:** Multi-party AI agent marketplaces where agents from different organizations need to establish mutual trust. +## Proof Engine -**Status:** Planned for a future protocol version. See [ROADMAP.md](../ROADMAP.md). +The MVP proof engine supports `cleartext-dev` mode. This mode is useful for examples, local development, and protocol review. ---- +Future proof engines may support signed claims, issuer registries, replay protection, receipt hash binding, and ZKP-compatible verification. -## Trust Authority: Internal Architecture +## Output Result -A production Trust Authority deployment: +The output is JSON designed to be consumed by runtime authority systems: +```json +{ + "subject": "agent:invoice_reviewer", + "effective_score": 0.84, + "required_score": 0.75, + "result": "TRUST_PROOF_VALID", + "reason": "effective trust score meets threshold", + "proof_mode": "cleartext-dev", + "evaluated_at": "2026-05-11T12:30:00.000Z" +} ``` - ┌─────────────────────────────────────────┐ - │ Trust Authority │ - │ │ - Issuers ─────────►│ POST /v1/receipts │ - │ → verify signature │ - │ → deduplicate (Redis SET) │ - │ → store (PostgreSQL/DynamoDB) │ - │ │ - Agents ──────────►│ POST /v1/tokens │ - │ → load receipts from DB │ - │ → run aggregation algorithm │ - │ → sign JWT (HSM/KMS) │ - │ → return token │ - │ │ - Verifiers ────────►│ GET /.well-known/ttp-keys │ - (key refresh) │ → return current public keyset │ - │ │ - └─────────────────────────────────────────┘ - │ │ - ▼ ▼ - ┌─────────┐ ┌─────────┐ - │ Redis │ │Postgres │ - │ (dedup, │ │(receipts│ - │ cache) │ │ store) │ - └─────────┘ └─────────┘ -``` - -### Persistence Requirements - -| Data | Store | TTL | -|------|-------|-----| -| Accepted receipt IDs (dedup) | Redis SET | receipt_max_age (24h) | -| Receipt content | PostgreSQL / DynamoDB | receipt_window + buffer (e.g., 1 hour) | -| Issued token JTIs (replay) | Redis SET | token TTL | -| Issuer public keys | PostgreSQL | indefinite (managed) | - ---- - -## Verifier: Integration Patterns - -### Pattern 1: Express Middleware (TypeScript) - -```typescript -import { createTTPMiddleware } from "@ttp/sdk" - -app.use("/api/sensitive", createTTPMiddleware({ - domain: "financial", - minScore: 0.90, - authorityPublicKey: process.env.TTP_AUTHORITY_PUBLIC_KEY, - minIssuerCount: 3, - replayDetection: true -})) -``` - -### Pattern 2: Service Mesh (Envoy / Istio) - -For polyglot environments, the TTP Verifier can run as a sidecar or Envoy external authorization filter: - -```yaml -# Envoy ExtAuthz configuration -http_filters: - - name: envoy.filters.http.ext_authz - typed_config: - "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz - grpc_service: - envoy_grpc: - cluster_name: ttp_verifier_sidecar - transport_api_version: V3 - # TTP verifier sidecar runs locally, sub-millisecond latency -``` - -### Pattern 3: API Gateway Plugin - -For Kong, AWS API Gateway, or Nginx, TTP verification can run as a plugin at the gateway layer, before requests reach any service. - -See [examples/service-integration](../examples/service-integration/) for Kong and Nginx configurations. - ---- - -## 10. GitHub Self-Governance Extension (TTP Governing TTP) - -TTP can be applied to its own repository operations by treating AI role-agents as governed workload identities and routing meaningful GitHub actions through a Runtime Authority Gate (`POST /re/authorize`) before execution. - -Reference materials: -- [GitHub Self-Governance Reference Architecture](github-self-governance-reference-architecture.md) -- [SCIM-RE Mapping Appendix](scim-re-github-role-agent-mapping.md) -- [ExecutionReceipt schema extension](../spec/extensions/execution-receipt-v2.schema.json) -- [Role-agent manifests](../agents/manifests/role-agents.yaml) - ---- - -## Performance Considerations - -### Token Verification Latency - -Ed25519 signature verification: ~0.04ms -JWT parsing and claim inspection: ~0.1ms -Total verifier overhead: **< 1ms** on commodity hardware (well under the 5ms target) -The bottleneck is not verification — it's token issuance (database reads, aggregation computation). This is amortized over the token TTL. +## Integration With RAP and SCIM-RE -### Token Issuance Latency +SCIM-RE provides runtime execution resource models such as `WorkloadIdentity`, `AuthorityGrant`, `Attestation`, `ExecutionRequest`, and `ExecutionReceipt`. -| Component | Typical | P99 | -|-----------|---------|-----| -| Receipt DB read (window) | 5ms | 20ms | -| Aggregation computation | < 1ms | 2ms | -| Ed25519 signing (software) | < 1ms | 2ms | -| Ed25519 signing (HSM) | 3ms | 15ms | -| **Total (software key)** | **~6ms** | **~25ms** | -| **Total (HSM)** | **~9ms** | **~40ms** | +RAP evaluates runtime authority decisions such as `PERMIT`, `STEP_UP`, `DENY`, `THROTTLE`, `ESCALATE`, and `CONSTRAIN`. -For a 300-second token TTL, each agent needs to call the TA approximately once every 4 minutes. A single TA instance can handle thousands of agents. +TTP provides the trust context that can feed those systems. -### Scaling +## Future ZKP Backend -| Component | Scaling Strategy | -|-----------|-----------------| -| Trust Authority | Stateless behind load balancer; shared Redis + DB | -| Issuers | Scale independently per issuer type | -| Verifiers | Embedded in service; scales with service | -| Redis (dedup) | Redis Cluster for large deployments | -| PostgreSQL (receipts) | Read replicas for high-volume issuers | +ZKP support is a future proof backend. It should allow selective disclosure of trust satisfaction without exposing raw trust scores or evidence. It is not required for the MVP. diff --git a/docs/integration-patterns.md b/docs/integration-patterns.md new file mode 100644 index 0000000..8845315 --- /dev/null +++ b/docs/integration-patterns.md @@ -0,0 +1,52 @@ +# Integration Patterns + +TTP is most useful when a runtime control point can evaluate trust before execution and fail closed when trust is insufficient. + +## AI Agent Runtime + +- **What calls TTP:** Agent runtime or tool executor. +- **What TTP evaluates:** Subject trust, tool/action scope, proof freshness, threshold, decay. +- **What happens next:** Runtime allows tool call, requests step-up through RAP, or blocks execution. +- **Where other layers fit:** SCIM-RE models workload and grant; RAP returns the decision; FrontDesk displays receipts and approval trails. + +## GitHub Actions + +- **What calls TTP:** Protected workflow step or pre-deploy gate. +- **What TTP evaluates:** Pipeline subject, repository scope, issuer trust, deployment authority threshold. +- **What happens next:** Workflow proceeds, pauses for approval, or fails closed. +- **Where other layers fit:** RAP can map result to `PERMIT`, `STEP_UP`, or `DENY`; Execution Exchange can enforce protected routes. + +## Azure DevOps + +- **What calls TTP:** Pipeline task before environment deployment or service connection use. +- **What TTP evaluates:** Pipeline identity, environment scope, recent attestation, threshold, expiration. +- **What happens next:** Deployment continues only if current trust satisfies the authority context. +- **Where other layers fit:** SCIM-RE models workload identity and authority grant; FrontDesk can show approval evidence. + +## API Gateway + +- **What calls TTP:** Gateway plugin, sidecar, or external authorization service. +- **What TTP evaluates:** API caller trust, action/resource scope, proof mode, threshold. +- **What happens next:** Gateway forwards, constrains, throttles, or rejects the request. +- **Where other layers fit:** RAP owns decision semantics; Execution Exchange owns route enforcement. + +## MCP Tool Gateway + +- **What calls TTP:** MCP tool gateway before tool invocation. +- **What TTP evaluates:** Agent subject, tool scope, issuer trust, freshness, and threshold. +- **What happens next:** Tool call is allowed, constrained, escalated, or denied. +- **Where other layers fit:** RAP supplies decision vocabulary; FrontDesk can show operator-visible evidence. + +## FrontDesk Runtime Authority Gate + +- **What calls TTP:** FrontDesk-integrated authority gate. +- **What TTP evaluates:** Business action trust, proof freshness, delegated authority, and evidence references. +- **What happens next:** FrontDesk presents approval, receipt, or escalation workflow. +- **Where other layers fit:** SCIM-RE models execution receipt; RAP returns authority decision. + +## NHI Governance Workflow + +- **What calls TTP:** Governance workflow or posture engine. +- **What TTP evaluates:** Non-human identity trust, lifecycle state, issuer claims, scope, decay. +- **What happens next:** Governance system updates posture, recommends constraints, or blocks high-risk activity through runtime controls. +- **Where other layers fit:** VerifiedTrust manages posture and lifecycle; TTP remains the portable trust grammar. diff --git a/docs/protocol-security-model.md b/docs/protocol-security-model.md new file mode 100644 index 0000000..57dfce4 --- /dev/null +++ b/docs/protocol-security-model.md @@ -0,0 +1,56 @@ +# Protocol Security Model + +TTP assumes trust is temporary, scoped, issuer-bound, and evaluated before execution. + +## Trust Is Not Permanent + +A valid trust claim at one time does not imply future trust. TTP documents must include expiration, and runtime systems should reject stale or missing trust context. + +## Trust Decays + +Trust may decline after issuance. The decay model prevents long-lived trust from being treated as equally strong over time. + +The MVP supports linear decay. Future versions may add risk-event and issuer-specific decay models. + +## Trust Must Be Scoped + +Trust should be bound to: + +- Subject. +- Domain. +- Scope. +- Action. +- Resource. +- Issuer. + +Broad trust claims should be treated as higher risk. + +## Trust Must Expire + +`expires_at` is mandatory for meaningful trust claims. Expired trust must fail, even when the effective score would otherwise meet a threshold. + +## Trust Issuers Must Be Validated + +An evaluator must know which issuers are allowed for which domains and scopes. The MVP documents issuer fields but does not implement a production issuer registry. + +## Proof Freshness Matters + +High-risk actions may require proof freshness that is shorter than claim expiration. A six-hour trust claim may still be too old for a production deployment or payment action. + +## TTP Is Not Enforcement By Itself + +TTP produces trust context and evaluation results. It does not stop execution unless a runtime control point uses the result. + +## Runtime Enforcement Must Fail Closed + +Runtime layers should reject execution when: + +- TTP parsing fails. +- The subject is unknown. +- The trust claim is missing. +- The proof is expired or stale. +- The effective score is below threshold. +- The proof mode is unsupported. +- The issuer is not accepted. + +Fail-open behavior defeats the purpose of execution-time trust. diff --git a/docs/ttp-vs-existing-standards.md b/docs/ttp-vs-existing-standards.md new file mode 100644 index 0000000..76669fe --- /dev/null +++ b/docs/ttp-vs-existing-standards.md @@ -0,0 +1,35 @@ +# TTP vs Existing Standards + +TTP is complementary to existing identity, policy, credential, and visibility systems. It should not be positioned as a replacement for mature standards that solve different layers. + +Core point: + +> Existing systems prove identity, access, credentials, policy, or event visibility. TTP expresses live, decaying, transferable trust context for execution-time authority evaluation. + +| Standard | Primary Function | What It Does Well | What TTP Adds | +| --- | --- | --- | --- | +| OAuth 2.0 | Delegated authorization framework. | Access tokens, consent, delegated API access. | Live trust context and decay before execution. | +| OIDC | Identity layer on OAuth 2.0. | Authentication, identity claims, federation. | Trust proof requirements beyond identity. | +| SAML | Enterprise federation and assertions. | Browser SSO and enterprise identity federation. | Execution-time trust freshness and decay. | +| SCIM | Identity lifecycle provisioning. | User and group provisioning across systems. | Runtime trust claims for autonomous actors. | +| SPIFFE/SPIRE | Workload identity. | Strong workload identities and mTLS integration. | Trust score, proof, delegation, and decay semantics. | +| OPA/Rego | General policy evaluation. | Flexible policy-as-code decisions. | A specific trust expression grammar OPA can consume. | +| Cedar | Authorization policy language. | Fine-grained app authorization. | Time-decaying trust context as an input to authorization. | +| X.509/PKI | Certificates and public key trust. | Identity, signing, TLS, certificate chains. | Scoped trust claims that change over time. | +| Verifiable Credentials | Tamper-evident credentials. | Issuer-holder-verifier credential exchange. | Execution-time trust decay and authority context. | +| DIDs | Decentralized identifiers. | Identifier control and resolution patterns. | Trust evaluation semantics over identified actors. | +| PAM | Privileged access management. | Human privileged session control and approvals. | Trust context for agents, workloads, and automated execution. | +| NHI governance tools | Inventory and governance of non-human identities. | Lifecycle, posture, ownership, compliance. | Portable protocol grammar for live trust before action. | +| API gateways | Traffic control and enforcement. | Routing, authn/z plugins, rate limits, enforcement. | Trust context the gateway can evaluate or forward. | +| SIEM/SOAR | Security visibility and automation. | Event collection, detection, response workflows. | Pre-execution trust proof rather than post-event visibility. | + +## Integration Posture + +TTP should be used with existing standards rather than instead of them. For example: + +- OIDC authenticates the actor. +- SPIFFE identifies the workload. +- OPA/Cedar evaluates policy. +- TTP supplies decaying trust context. +- RAP decides runtime authority. +- Execution Exchange or an API gateway enforces the result. diff --git a/docs/ttp-vs-rap-vs-scim-re.md b/docs/ttp-vs-rap-vs-scim-re.md new file mode 100644 index 0000000..174e821 --- /dev/null +++ b/docs/ttp-vs-rap-vs-scim-re.md @@ -0,0 +1,75 @@ +# TTP vs RAP vs SCIM-RE + +TTP, SCIM-RE, RAP, Execution Exchange, FrontDesk, and VerifiedTrust are separate layers. TTP should not claim the responsibilities of the other layers. + +## Layer Comparison + +| Layer | Primary Responsibility | Example Artifacts | TTP Boundary | +| --- | --- | --- | --- | +| TTP | Expresses trust claims, trust decay, trust transfer, delegation, proof requirements, and authority context. | `.ttp` files, trust claims, proofs, evaluation result JSON. | Produces trust context that runtime systems can evaluate. | +| SCIM-RE | Defines runtime execution governance resources. | `WorkloadIdentity`, `AuthorityGrant`, `Attestation`, `ExecutionRequest`, `ExecutionReceipt`. | Can consume TTP subject, trust, and attestation fields. | +| RAP | Defines runtime authority decision exchange before action. | Requests/responses with `PERMIT`, `STEP_UP`, `DENY`, `THROTTLE`, `ESCALATE`, `CONSTRAIN`. | Can use TTP evaluation as one input to runtime decisions. | +| Execution Exchange | Gateway that enforces RAP decisions across routes and runtime integrations. | Enforcement routes, gateway policy, receipts. | Calls RAP before execution and may pass TTP context. | +| FrontDesk | Business and operator control plane. | Approvals, receipts, agents, outcomes, customer impact views. | Displays evidence and approval trails informed by TTP/RAP/SCIM-RE. | +| VerifiedTrust | Enterprise NHI posture and governance platform. | Policy, lifecycle, compliance, identity posture. | May issue, manage, or validate trust claims, but TTP remains portable. | + +## TTP + +TTP expresses: + +- Trust claims. +- Trust decay. +- Trust transfer. +- Delegation. +- Proof requirements. +- Authority context. + +It produces trust context and evaluation results. It does not enforce execution by itself. + +## SCIM-RE + +SCIM-RE defines runtime execution governance resources: + +- `WorkloadIdentity` +- `AuthorityGrant` +- `Attestation` +- `ExecutionRequest` +- `ExecutionReceipt` + +SCIM-RE provides the resource model that runtime systems can use to represent who acted, under which grant, with what evidence, and what receipt was produced. + +## RAP + +RAP is the Runtime Authority Protocol. It defines the decision exchange before execution. + +RAP decisions include: + +- `PERMIT` +- `STEP_UP` +- `DENY` +- `THROTTLE` +- `ESCALATE` +- `CONSTRAIN` + +RAP evaluates runtime context, policy, trust, risk, and required controls before action. + +## Execution Exchange + +Execution Exchange is the enforcement layer. It calls RAP before execution, applies the decision across routes or runtime integrations, and produces or forwards receipts. + +## FrontDesk + +FrontDesk is the operator and business control plane. It shows approvals, receipts, agents, outcomes, customer impact, and escalation trails. + +## VerifiedTrust + +VerifiedTrust is the enterprise NHI posture and governance platform. It manages policies, identity posture, lifecycle, and compliance views. + +## Example Flow + +1. Agent wants to update a CRM record. +2. Agent presents TTP trust context. +3. SCIM-RE identifies the workload and grant. +4. RAP evaluates the runtime decision. +5. Execution Exchange enforces the decision. +6. FrontDesk shows receipt and approval trail. diff --git a/examples/01-basic-agent.ttp b/examples/01-basic-agent.ttp new file mode 100644 index 0000000..841bd2e --- /dev/null +++ b/examples/01-basic-agent.ttp @@ -0,0 +1,36 @@ +subject "agent:invoice_reviewer" { + type = "ai_agent" + issuer = "blocksifr.local" + domain = "finance" +} + +trust "agent:invoice_reviewer" { + issuer = "verifiedtrust:tenant_123" + score = 0.86 + issued_at = "2026-05-11T12:00:00Z" + expires_at = "2026-05-11T18:00:00Z" + + decay { + model = "linear" + half_life = "6h" + minimum = 0.40 + } + + scope = [ + "invoice.read", + "invoice.recommend" + ] +} + +proof "invoice_review_threshold" { + subject = "agent:invoice_reviewer" + required_score = 0.75 + mode = "cleartext-dev" + freshness = "30m" +} + +authority_context "invoice_review" { + action = "invoice.recommend" + resource = "invoice:*" + requires = proof.invoice_review_threshold +} diff --git a/examples/02-trust-decay.ttp b/examples/02-trust-decay.ttp new file mode 100644 index 0000000..10ea79c --- /dev/null +++ b/examples/02-trust-decay.ttp @@ -0,0 +1,36 @@ +subject "agent:invoice_reviewer" { + type = "ai_agent" + issuer = "blocksifr.local" + domain = "finance" +} + +trust "agent:invoice_reviewer" { + issuer = "verifiedtrust:tenant_123" + score = 0.90 + issued_at = "2026-05-11T12:00:00Z" + expires_at = "2026-05-11T20:00:00Z" + + decay { + model = "linear" + half_life = "4h" + minimum = 0.30 + } + + scope = [ + "invoice.read", + "invoice.recommend" + ] +} + +proof "invoice_review_threshold" { + subject = "agent:invoice_reviewer" + required_score = 0.70 + mode = "cleartext-dev" + freshness = "8h" +} + +authority_context "invoice_review" { + action = "invoice.recommend" + resource = "invoice:*" + requires = proof.invoice_review_threshold +} diff --git a/examples/03-threshold-proof.ttp b/examples/03-threshold-proof.ttp new file mode 100644 index 0000000..45fa5eb --- /dev/null +++ b/examples/03-threshold-proof.ttp @@ -0,0 +1,36 @@ +subject "pipeline:prod_deployer" { + type = "automation_pipeline" + issuer = "blocksifr.local" + domain = "platform" +} + +trust "pipeline:prod_deployer" { + issuer = "verifiedtrust:tenant_123" + score = 0.93 + issued_at = "2026-05-11T13:00:00Z" + expires_at = "2026-05-11T15:00:00Z" + + decay { + model = "linear" + half_life = "2h" + minimum = 0.60 + } + + scope = [ + "deploy.read", + "deploy.execute" + ] +} + +proof "production_deploy_threshold" { + subject = "pipeline:prod_deployer" + required_score = 0.90 + mode = "cleartext-dev" + freshness = "20m" +} + +authority_context "production_deploy" { + action = "deploy.execute" + resource = "service:payments-api" + requires = proof.production_deploy_threshold +} diff --git a/examples/04-delegated-trust.ttp b/examples/04-delegated-trust.ttp new file mode 100644 index 0000000..6a88088 --- /dev/null +++ b/examples/04-delegated-trust.ttp @@ -0,0 +1,54 @@ +subject "agent:invoice_reviewer" { + type = "ai_agent" + issuer = "blocksifr.local" + domain = "finance" +} + +subject "agent:payment_exception_reviewer" { + type = "ai_agent" + issuer = "blocksifr.local" + domain = "finance" +} + +trust "agent:invoice_reviewer" { + issuer = "verifiedtrust:tenant_123" + score = 0.88 + issued_at = "2026-05-11T12:00:00Z" + expires_at = "2026-05-11T18:00:00Z" + + decay { + model = "linear" + half_life = "6h" + minimum = 0.45 + } + + scope = [ + "invoice.read", + "invoice.recommend", + "invoice.exception.delegate" + ] +} + +delegation "review_to_payment_exception" { + from = "agent:invoice_reviewer" + to = "agent:payment_exception_reviewer" + issuer = "verifiedtrust:tenant_123" + scope = [ + "invoice.exception.review" + ] + max_score = 0.72 + expires_at = "2026-05-11T16:00:00Z" +} + +proof "delegated_exception_threshold" { + subject = "agent:invoice_reviewer" + required_score = 0.70 + mode = "cleartext-dev" + freshness = "1h" +} + +authority_context "payment_exception_review" { + action = "invoice.exception.review" + resource = "invoice:*" + requires = proof.delegated_exception_threshold +} diff --git a/examples/05-frontdesk-authority-context.ttp b/examples/05-frontdesk-authority-context.ttp new file mode 100644 index 0000000..02ea968 --- /dev/null +++ b/examples/05-frontdesk-authority-context.ttp @@ -0,0 +1,40 @@ +subject "service_account:frontdesk_runtime_gate" { + type = "service_account" + issuer = "blocksifr.local" + domain = "customer-operations" +} + +trust "service_account:frontdesk_runtime_gate" { + issuer = "verifiedtrust:tenant_123" + score = 0.91 + issued_at = "2026-05-11T12:15:00Z" + expires_at = "2026-05-11T14:15:00Z" + + decay { + model = "linear" + half_life = "2h" + minimum = 0.55 + } + + scope = [ + "customer.approval.present", + "execution.receipt.record" + ] + + evidence = [ + "receipt:frontdesk_gate_health_20260511" + ] +} + +proof "frontdesk_gate_threshold" { + subject = "service_account:frontdesk_runtime_gate" + required_score = 0.80 + mode = "cleartext-dev" + freshness = "45m" +} + +authority_context "customer_impacting_action" { + action = "customer.approval.present" + resource = "customer:*" + requires = proof.frontdesk_gate_threshold +} diff --git a/package.json b/package.json index dc8fb59..97f0d29 100644 --- a/package.json +++ b/package.json @@ -2,8 +2,15 @@ "name": "ttp-protocol-workspace", "private": true, "type": "module", + "bin": { + "ttp": "./src/index.js" + }, "scripts": { "demo": "node examples/local-trust-gate-demo.mjs", - "test:trust-routing": "node --test packages/trust-routing-engine/tests/*.test.mjs" + "ttp": "node src/index.js", + "test": "node --test tests/*.test.mjs packages/trust-routing-engine/tests/*.test.mjs", + "test:ttp": "node --test tests/*.test.mjs", + "test:trust-routing": "node --test packages/trust-routing-engine/tests/*.test.mjs", + "check:examples": "node src/index.js check examples/01-basic-agent.ttp && node src/index.js check examples/02-trust-decay.ttp && node src/index.js check examples/03-threshold-proof.ttp && node src/index.js check examples/04-delegated-trust.ttp && node src/index.js check examples/05-frontdesk-authority-context.ttp" } } diff --git a/protocol/spec.md b/protocol/spec.md index e4c48b9..8f6ccba 100644 --- a/protocol/spec.md +++ b/protocol/spec.md @@ -1,1062 +1,19 @@ -# Trust Transfer Protocol — Specification v1.0 +# Protocol Spec Note -**Status:** Stable -**Authors:** BlockSiFr -**Date:** 2026 -**License:** Apache 2.0 +The active Trust Transfer Protocol draft is maintained at [`../SPECIFICATION.md`](../SPECIFICATION.md). ---- +This `protocol/` directory contains earlier token, receipt, aggregation, schema, and test-vector work that may inform future signed-claim and runtime integration phases. It should be treated as reference material, not the current stable protocol contract. -## Table of Contents +Current status: -1. [Introduction](#1-introduction) -2. [Terminology](#2-terminology) -3. [Protocol Overview](#3-protocol-overview) -4. [Actors and Roles](#4-actors-and-roles) -5. [Behavioral Receipts](#5-behavioral-receipts) -6. [Receipt Submission](#6-receipt-submission) -7. [Trust Score Computation](#7-trust-score-computation) -8. [Trust Token Issuance](#8-trust-token-issuance) -9. [Trust Token Verification](#9-trust-token-verification) -10. [Token Presentation](#10-token-presentation) -11. [Domain Scoping](#11-domain-scoping) -12. [Agent Lifecycle](#12-agent-lifecycle) -13. [Cryptographic Requirements](#13-cryptographic-requirements) -14. [Versioning](#14-versioning) -15. [Error Codes](#15-error-codes) -16. [Conformance](#16-conformance) +- Protocol specification draft complete. +- Reference implementation in active development. +- Current milestone: MVP parser + trust decay evaluator. +- Production use: not yet recommended. ---- +For the current scope and grammar, see: -## 1. Introduction - -Trust Transfer Protocol (TTP) is an open protocol for **runtime behavioral trust verification** of autonomous agents and automated systems. - -Existing identity and authorization protocols — OAuth 2.0, mTLS, IAM systems — establish *who* a system is. They do not answer whether that system is currently trustworthy based on its observed behavior. This gap is acceptable for human-operated systems where sessions are short and humans provide implicit behavioral feedback. For autonomous AI agents, which may operate continuously and make high-consequence decisions without human oversight, the gap is a structural security risk. - -TTP fills this gap by introducing a trust layer that: - -1. Collects **behavioral receipts** from independent observers (issuers) -2. **Aggregates** receipts into a scored trust signal -3. Issues **short-lived signed tokens** encoding that trust signal -4. Enables **stateless service-side verification** without contacting the Trust Authority - -The protocol is transport-agnostic. This specification uses HTTP as the primary transport. All data structures are JSON. - -### 1.1 Design Goals - -- **Correctness** — Trust tokens reflect verifiable behavioral evidence. -- **Freshness** — Short token lifetimes ensure trust reflects recent behavior. -- **Statelessness** — Verifiers do not contact the Trust Authority at verification time. -- **Independence** — No single issuer can control an agent's trust score. -- **Privacy** — Zero-Knowledge Proof extensions allow trust verification without revealing score values. -- **Interoperability** — Any conformant implementation of any component is substitutable. -- **Performance** — Token verification completes in under 5ms on commodity hardware. - -### 1.2 Non-Goals - -- TTP does not replace identity protocols (OAuth, OIDC, mTLS, SPIFFE). -- TTP does not provide authorization (IAM) or network-level access control (ZTNA). -- TTP does not define how issuers observe agent behavior. This is issuer-specific. -- TTP does not define AI safety evaluation methods. Issuers apply domain-appropriate logic. - ---- - -## 2. Terminology - -The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://www.rfc-editor.org/rfc/rfc2119). - -| Term | Definition | -|------|------------| -| **Agent** | An autonomous system (AI agent, bot, automated pipeline) whose trustworthiness is being evaluated. | -| **Issuer** | An independent observer that generates signed behavioral receipts attesting to an agent's behavior. | -| **Trust Authority** | A service that aggregates receipts and issues trust tokens. | -| **Verifier** | A service that validates trust tokens before granting access or executing actions. | -| **Behavioral Receipt** | A signed, tamper-evident record of observed agent behavior produced by an issuer. | -| **Trust Score** | A floating-point value in [0.0, 1.0] representing aggregated behavioral trust. | -| **Trust Token** | A short-lived signed JWT encoding an agent's current trust score for a specific domain. | -| **Domain** | A named operational scope (e.g., `retention`, `financial`, `infra`) isolating trust evaluation. | -| **Receipt Window** | The time span of behavioral history aggregated into a trust token. | -| **Cold Start** | The state of an agent that has no behavioral history with the Trust Authority. | - ---- - -## 3. Protocol Overview - -``` -┌───────────┐ actions ┌─────────────┐ signed receipts ┌──────────────────┐ -│ Agent │ ──────────► │ Issuers │ ────────────────► │ Trust Authority │ -└───────────┘ └─────────────┘ └────────┬─────────┘ - │ │ - │ (1) request token │ (2) aggregate + score - │ ─────────────────────────────────────────────────────────► │ - │ │ (3) issue token - │ ◄────────────────────────────────────────────────────────── │ - │ trust token │ - │ │ - │ (4) present token │ - │ ─────────────────────────────────────────────────────► │ - ▼ │ -┌─────────────────┐ │ -│ Verifier │ (5) stateless verification (no network call) │ -│ (Service) │ ◄─────────────────────────────────────────────── │ -└────────┬────────┘ (Authority public key, cached at startup) - │ - ▼ - allow / deny -``` - -**Step 1 — Receipt generation:** Issuers observe agent actions and produce signed behavioral receipts. Receipts are submitted to the Trust Authority asynchronously. - -**Step 2 — Aggregation:** The Trust Authority verifies receipt signatures, deduplicates receipts, and applies the aggregation algorithm (see [protocol/aggregation-spec.md](aggregation-spec.md)) to compute a trust score. - -**Step 3 — Token issuance:** The Trust Authority signs and returns a trust token containing the computed score, domain, and expiration. - -**Step 4 — Token presentation:** The agent presents the trust token in the `X-TTP-Token` HTTP header when calling protected services. - -**Step 5 — Stateless verification:** The verifier validates the token signature using the Trust Authority's public key (fetched once at startup), checks freshness, domain, and score threshold. No network call is required. - ---- - -## 4. Actors and Roles - -### 4.1 Agent - -The agent is the entity whose trustworthiness is being evaluated. An agent: - -- MUST have a stable, unique identifier (`agent_id`) -- MUST hold an Ed25519 keypair used for signing receipt submissions to the Trust Authority -- MUST request trust tokens from a Trust Authority before calling protected services -- MUST present the trust token in the `X-TTP-Token` header - -An `agent_id` is a non-empty string that is unique within a Trust Authority's namespace. The RECOMMENDED format is a UUID v4. The Trust Authority MUST treat `agent_id` as case-sensitive. - -### 4.2 Issuer - -An issuer observes agent behavior and produces behavioral receipts. An issuer: - -- MUST have a stable, unique identifier (`issuer_id`) -- MUST hold an Ed25519 keypair for signing receipts -- MUST register its public key with the Trust Authority before receipts are accepted -- MUST produce receipts that conform to the receipt schema -- SHOULD operate independently of other issuers -- SHOULD NOT have a business relationship that would create incentive to inflate or suppress scores - -Multiple issuers for the same agent RECOMMENDED. A Trust Authority MAY require a minimum issuer count before issuing a token. - -**Example issuer types:** API gateways, tool execution sandboxes, inference monitoring services, security scanners, rate-limiting layers. - -### 4.3 Trust Authority - -The Trust Authority is the core aggregation and issuance service. It: - -- MUST verify the cryptographic signature on all receipts before accepting them -- MUST deduplicate receipts by `receipt_id` -- MUST compute trust scores using the algorithm specified in [aggregation-spec.md](aggregation-spec.md) -- MUST sign trust tokens with its Ed25519 private key -- MUST publish its public key at a well-known endpoint -- MUST NOT issue tokens with TTL exceeding 600 seconds (10 minutes) -- SHOULD issue tokens with TTL of 300 seconds or less -- SHOULD apply temporal decay to receipts older than the configured `receipt_window` - -The Trust Authority's signing key is the root of trust for all verifiers. Key rotation procedures are described in [docs/security.md](../docs/security.md). - -### 4.4 Verifier - -A verifier is a service that enforces trust requirements. It: - -- MUST fetch and cache the Trust Authority's public key at startup -- MUST validate the token signature -- MUST reject tokens where `exp < current_time` -- MUST reject tokens where `ttp_domain` does not match the expected domain -- MUST reject tokens where `ttp_score < required_score` -- SHOULD apply a clock skew tolerance of no more than 30 seconds -- SHOULD refresh the cached Trust Authority public key at least every 24 hours -- MAY cache verified tokens by `jti` for their remaining lifetime to avoid re-verification overhead - ---- - -## 5. Behavioral Receipts - -### 5.1 Schema - -A behavioral receipt is a JSON object conforming to [schemas/receipt.schema.json](schemas/receipt.schema.json). - -```json -{ - "ttp_version": "1.0", - "receipt_id": "550e8400-e29b-41d4-a716-446655440000", - "agent_id": "agent-prod-abc123", - "issuer_id": "issuer-api-gateway-01", - "event_type": "api_call", - "event_data": { - "method": "POST", - "path": "/api/issue-discount", - "status": 200, - "latency_ms": 43 - }, - "domain": "retention", - "timestamp": 1700000000000, - "score": 0.92, - "signature": "base64url(Ed25519_signature_over_canonical_payload)" -} -``` - -### 5.2 Field Definitions - -| Field | Type | Required | Description | -|-------|------|----------|-------------| -| `ttp_version` | string | REQUIRED | Protocol version. MUST be `"1.0"` for this specification. | -| `receipt_id` | string | REQUIRED | UUID v4. MUST be unique per issuer. Used for deduplication. | -| `agent_id` | string | REQUIRED | The agent this receipt attests to. | -| `issuer_id` | string | REQUIRED | The issuer producing this receipt. | -| `event_type` | string | REQUIRED | Categorizes the observed event. See [scoring-semantics.md](scoring-semantics.md). | -| `event_data` | object | OPTIONAL | Issuer-specific event context. MUST NOT contain PII. | -| `domain` | string | REQUIRED | The trust domain this receipt applies to. | -| `timestamp` | integer | REQUIRED | Unix timestamp in milliseconds when the event was observed. | -| `score` | number | REQUIRED | Issuer's behavioral assessment: [0.0, 1.0]. See [scoring-semantics.md](scoring-semantics.md). | -| `signature` | string | REQUIRED | Base64url-encoded Ed25519 signature over the canonical payload. | - -### 5.3 Canonical Signing Payload - -The signature covers a deterministic serialization of the receipt fields. The canonical payload is the JSON object with all fields **except `signature`**, keys sorted lexicographically, no whitespace: - -``` -sign(Ed25519_private_key, SHA256(canonical_json_bytes)) -``` - -Implementations MUST use this exact canonicalization. Deviation produces signature verification failures. - -**Example canonical payload:** - -```json -{"agent_id":"agent-prod-abc123","domain":"retention","event_data":{"latency_ms":43,"method":"POST","path":"/api/issue-discount","status":200},"event_type":"api_call","issuer_id":"issuer-api-gateway-01","receipt_id":"550e8400-e29b-41d4-a716-446655440000","score":0.92,"timestamp":1700000000000,"ttp_version":"1.0"} -``` - -### 5.4 Receipt Validity Rules - -A Trust Authority MUST reject a receipt if: - -1. The `ttp_version` is not supported. -2. The `signature` fails Ed25519 verification against the registered issuer public key. -3. The `receipt_id` has already been seen (deduplication). -4. The `timestamp` is more than 300 seconds in the future (clock skew protection). -5. The `timestamp` is older than the configured maximum receipt age (RECOMMENDED: 86400 seconds / 24 hours). -6. The `score` is outside [0.0, 1.0]. -7. The `agent_id` is empty or absent. -8. The `issuer_id` is not registered with this Trust Authority. - ---- - -## 6. Receipt Submission - -### 6.1 Endpoint - -``` -POST /v1/receipts -``` - -### 6.2 Request - -```http -POST /v1/receipts HTTP/1.1 -Host: authority.example.com -Content-Type: application/json -Authorization: Bearer - -{ - "ttp_version": "1.0", - "receipt_id": "550e8400-e29b-41d4-a716-446655440000", - "agent_id": "agent-prod-abc123", - "issuer_id": "issuer-api-gateway-01", - "event_type": "api_call", - "event_data": { ... }, - "domain": "retention", - "timestamp": 1700000000000, - "score": 0.92, - "signature": "..." -} -``` - -Issuers MUST authenticate to the Trust Authority. The RECOMMENDED mechanism is an API key in the `Authorization` header. Future versions will support issuer-signed submissions. - -### 6.3 Response - -**Success (201 Created):** -```json -{ - "status": "accepted", - "receipt_id": "550e8400-e29b-41d4-a716-446655440000" -} -``` - -**Duplicate receipt (200 OK):** -```json -{ - "status": "duplicate", - "receipt_id": "550e8400-e29b-41d4-a716-446655440000" -} -``` - -**Validation failure (400 Bad Request):** -```json -{ - "error": "INVALID_SIGNATURE", - "message": "Receipt signature verification failed", - "receipt_id": "550e8400-e29b-41d4-a716-446655440000" -} -``` - -### 6.4 Batch Submission - -``` -POST /v1/receipts/batch -``` - -Accepts an array of up to 100 receipts. Returns per-receipt results. Partial success is allowed. - ---- - -## 7. Trust Score Computation - -See [aggregation-spec.md](aggregation-spec.md) for the complete algorithm. - -**Summary:** The Trust Authority applies a time-weighted, issuer-normalized aggregation over receipts within the configured `receipt_window`. The result is a float in [0.0, 1.0]. - -Key properties of the algorithm: - -- Receipts from a single issuer are capped to prevent single-issuer domination. -- Older receipts contribute less weight (exponential decay over `receipt_window`). -- Negative-signal receipts (score < 0.5) are weighted more heavily than positive-signal receipts to prevent recovery gaming. -- The algorithm is deterministic and reproducible given the same receipt set. - ---- - -## 8. Trust Token Issuance - -### 8.1 Endpoint - -``` -POST /v1/tokens -``` - -### 8.2 Request - -```http -POST /v1/tokens HTTP/1.1 -Host: authority.example.com -Content-Type: application/json -Authorization: Bearer - -{ - "agent_id": "agent-prod-abc123", - "domain": "retention", - "requested_ttl": 300 -} -``` - -The agent authenticates with its own API key (or agent-signed request in future versions). - -`requested_ttl` is OPTIONAL. The Trust Authority MAY issue a token with a shorter TTL than requested. The Trust Authority MUST NOT issue a token with a TTL exceeding 600 seconds. - -### 8.3 Response - -**Success (200 OK):** -```json -{ - "token": "", - "expires_at": 1700000300, - "score": 0.91, - "issuer_count": 3 -} -``` - -**Insufficient trust data (403 Forbidden):** -```json -{ - "error": "INSUFFICIENT_TRUST_DATA", - "message": "No receipts found for agent in domain 'retention' within the receipt window", - "min_issuer_count": 2, - "current_issuer_count": 0 -} -``` - -### 8.4 Trust Token JWT Structure - -The trust token is a signed JWT ([RFC 7519](https://www.rfc-editor.org/rfc/rfc7519)). - -**Header:** -```json -{ - "alg": "EdDSA", - "kid": "authority-key-2026-01", - "typ": "JWT" -} -``` - -**Payload:** -```json -{ - "ttp_version": "1.0", - "sub": "agent-prod-abc123", - "iss": "https://authority.example.com", - "iat": 1700000000, - "exp": 1700000300, - "jti": "tok_7f3d9a2b1e4c8f6a", - "ttp_domain": "retention", - "ttp_score": 0.91, - "ttp_issuer_count": 3, - "ttp_receipt_window": 300 -} -``` - -### 8.5 Token Claim Definitions - -| Claim | Type | Description | -|-------|------|-------------| -| `ttp_version` | string | Protocol version. | -| `sub` | string | Agent identifier. | -| `iss` | string | Trust Authority base URL. | -| `iat` | integer | Unix timestamp of issuance. | -| `exp` | integer | Unix timestamp of expiration. | -| `jti` | string | Unique token ID. Used for replay detection by verifiers. | -| `ttp_domain` | string | Domain scope of this token. | -| `ttp_score` | number | Aggregated trust score [0.0, 1.0]. | -| `ttp_issuer_count` | integer | Number of distinct issuers contributing receipts. | -| `ttp_receipt_window` | integer | Seconds of behavioral history aggregated. | - ---- - -## 9. Trust Token Verification - -Verification is performed by the verifier at request time. No network call is required. - -### 9.1 Verification Algorithm - -A verifier MUST perform the following steps in order. Failure at any step MUST result in rejection. - -``` -1. Decode the JWT header and payload (no verification yet). -2. Check ttp_version is supported. -3. Retrieve the Trust Authority public key matching kid in the JWT header. -4. Verify the JWT signature using the Trust Authority public key. -5. Check exp > current_time (with ≤30s clock skew tolerance). -6. Check ttp_domain == expected_domain. -7. Check ttp_score >= required_score. -8. (OPTIONAL) Check ttp_issuer_count >= required_issuer_count. -9. Grant access. -``` - -### 9.2 Verification HTTP Header - -Agents present the token in the `X-TTP-Token` header: - -```http -POST /api/issue-discount HTTP/1.1 -Host: service.example.com -X-TTP-Token: eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9... -Content-Type: application/json -``` - -### 9.3 Rejection Response - -When a verifier rejects a request, it MUST return HTTP 403 with a JSON body: - -```json -{ - "error": "TTP_VERIFICATION_FAILED", - "reason": "SCORE_BELOW_THRESHOLD", - "required_score": 0.85, - "token_score": 0.72, - "domain": "retention" -} -``` - -Valid `reason` values: `MISSING_TOKEN`, `INVALID_SIGNATURE`, `TOKEN_EXPIRED`, `DOMAIN_MISMATCH`, `SCORE_BELOW_THRESHOLD`, `UNSUPPORTED_VERSION`, `INSUFFICIENT_ISSUERS`. - ---- - -## 10. Token Presentation - -### 10.1 Caching - -Agents SHOULD cache trust tokens and reuse them until they are within 30 seconds of expiry. Requesting a new token for every request is unnecessary overhead and creates unnecessary load on the Trust Authority. - -### 10.2 Auto-Refresh - -Agents SHOULD implement automatic token refresh. The RECOMMENDED pattern: - -1. Fetch a token when first needed. -2. Track `expires_at`. -3. Refresh when `expires_at - current_time < 30s`. -4. On 403 with `SCORE_BELOW_THRESHOLD`: do not retry immediately. Trust is a function of behavior, not retries. -5. On Trust Authority unavailability: apply the fallback policy configured by the operator. - -### 10.3 Fallback Policies - -Operators configuring verifiers MUST explicitly choose a fallback policy for Trust Authority unavailability: - -| Policy | Behavior | Use Case | -|--------|----------|----------| -| `deny` | Reject all requests when no fresh token can be obtained | High-security, fail-closed | -| `cached` | Accept previously verified tokens up to N seconds past expiry | Availability-sensitive, bounded risk | -| `degrade` | Accept requests with reduced capability | Service continuity with safety bounds | - ---- - -## 11. Domain Scoping - -Domains isolate trust evaluation. A trust token issued for domain `retention` MUST NOT be accepted by a verifier enforcing domain `financial`. - -### 11.1 Domain Format - -Domains are lowercase alphanumeric strings with optional hyphens: `[a-z0-9][a-z0-9-]*[a-z0-9]`. - -### 11.2 Domain Hierarchies - -Domains MAY be hierarchical using dot notation: `financial.transactions`, `financial.reporting`. A token for `financial` does not satisfy `financial.transactions` — the match MUST be exact. Wildcard matching is not defined in this version. - -### 11.3 Cross-Domain Trust - -Trust earned in one domain does not automatically apply to another. An agent with high trust in `retention` starts fresh in `financial`. This is intentional: domains represent meaningfully different operational contexts with different risk profiles. - ---- - -## 12. Agent Lifecycle - -### 12.1 Cold Start - -A new agent has no behavioral history. The Trust Authority MUST return `INSUFFICIENT_TRUST_DATA` until: - -- At least `min_issuer_count` distinct issuers have submitted receipts within the `receipt_window` -- The minimum required receipts have accumulated - -The default `min_issuer_count` is 1. Operators SHOULD require 2 or more for sensitive domains. - -Cold start mitigation strategies: -- Pre-seed receipts from a test/staging environment before production launch. -- Implement a supervised initial period where an agent operates under human oversight and generates receipts. -- Use trust delegation from an established agent (see TTP Language specification). - -### 12.2 Trust Decay - -Receipt contributions decay over time. An agent that stops being observed gradually loses trust signal. This is intentional: stale behavioral history should not substitute for current behavior. - -Decay is applied by the aggregation algorithm. See [aggregation-spec.md](aggregation-spec.md). - -### 12.3 Agent Blocking - -A Trust Authority MAY refuse to issue tokens for an agent that has been administratively blocked. A blocked agent receives 403 with `error: AGENT_BLOCKED`. The Trust Authority SHOULD provide a reason and estimated unblock time. - ---- - -## 13. Cryptographic Requirements - -### 13.1 Signature Algorithm - -All signatures MUST use **Ed25519** as defined in [RFC 8037](https://www.rfc-editor.org/rfc/rfc8037). - -The choice of Ed25519: -- Deterministic (no per-signature randomness needed) -- Fast: ~14μs sign, ~40μs verify on commodity hardware -- Small: 64-byte signatures, 32-byte public keys -- Secure: ~128-bit security level - -### 13.2 JWT Algorithm - -Trust tokens MUST use the `EdDSA` algorithm identifier with the `Ed25519` curve as specified in [RFC 8037](https://www.rfc-editor.org/rfc/rfc8037). - -### 13.3 Key Rotation - -Trust Authority signing keys MUST be rotatable without service interruption. The process: - -1. Generate a new keypair. Assign a new `kid`. -2. Publish the new public key at the `/.well-known/ttp-keys` endpoint alongside the old key. -3. Begin signing new tokens with the new key. -4. Wait until all tokens signed with the old key have expired. -5. Remove the old public key from the published keyset. - -Verifiers that refresh public keys periodically will pick up the new key during normal operation. - -### 13.4 Key Publication - -Trust Authorities MUST publish their active signing public keys at: - -``` -GET /.well-known/ttp-keys -``` - -Response: -```json -{ - "keys": [ - { - "kid": "authority-key-2026-01", - "kty": "OKP", - "crv": "Ed25519", - "x": "base64url-encoded-public-key", - "use": "sig" - } - ] -} -``` - ---- - -## 14. Versioning - -### 14.1 Protocol Versioning - -The `ttp_version` field in receipts and trust tokens identifies the protocol version. This enables forward-compatible evolution. - -Current version: `"1.0"` - -### 14.2 Version Compatibility - -A Trust Authority MUST reject receipts with an unsupported `ttp_version`. - -A Verifier MUST reject tokens with an unsupported `ttp_version`. - -A Verifier SHOULD log a warning when it encounters a `ttp_version` it supports but which is older than its minimum recommended version. - -### 14.3 Specification Evolution - -Protocol changes are classified as: - -- **Patch** (1.0 → 1.0): Clarifications, examples, non-normative text. No implementation changes required. -- **Minor** (1.0 → 1.1): Backwards-compatible additions (new optional fields, new claim names). Old verifiers continue to work. -- **Major** (1.0 → 2.0): Breaking changes. New `ttp_version` value required. - -Changes follow the RFC process documented in [docs/governance.md](../docs/governance.md). - ---- - -## 15. Error Codes - -| Code | HTTP Status | Description | -|------|-------------|-------------| -| `INVALID_SIGNATURE` | 400 | Receipt or token signature failed verification. | -| `RECEIPT_DUPLICATE` | 200 | Receipt was already accepted (idempotent). | -| `RECEIPT_TOO_OLD` | 400 | Receipt timestamp is outside the accepted age window. | -| `RECEIPT_FUTURE_DATED` | 400 | Receipt timestamp is more than 300 seconds in the future. | -| `SCORE_OUT_OF_RANGE` | 400 | Receipt score is outside [0.0, 1.0]. | -| `ISSUER_NOT_REGISTERED` | 401 | Issuer is not registered with this Trust Authority. | -| `AGENT_NOT_FOUND` | 404 | No agent with this ID is known to the Trust Authority. | -| `AGENT_BLOCKED` | 403 | Agent has been administratively blocked. | -| `AGENT_QUARANTINED` | 403 | Agent is under quarantine and the verifier has `denyQuarantined: true`. | -| `INSUFFICIENT_TRUST_DATA` | 403 | Not enough receipts to compute a trust score. | -| `UNSUPPORTED_VERSION` | 400 | The `ttp_version` is not supported. | -| `TOKEN_EXPIRED` | 403 | Trust token has expired. | -| `DOMAIN_MISMATCH` | 403 | Token domain does not match required domain. | -| `SCORE_BELOW_THRESHOLD` | 403 | Token score is below the required threshold. | -| `MISSING_TOKEN` | 401 | No trust token was presented. | -| `INSUFFICIENT_ISSUERS` | 403 | Token was issued with fewer issuers than required. | -| `PEER_ATTESTER_INELIGIBLE` | 403 | Attesting agent does not meet peer issuer eligibility requirements. | -| `PEER_CONFIRMATION_DENIED` | 403 | External confirmation API rejected the peer receipt. | -| `PEER_CONFIRMATION_TIMEOUT` | 403 | External confirmation API did not respond within 2 seconds. | - ---- - -## 16. Conformance - -An implementation is a **conformant Trust Authority** if it: - -- Accepts receipt submissions conforming to the receipt schema -- Verifies receipt signatures before accepting receipts -- Deduplicates receipts by `receipt_id` -- Computes trust scores using the algorithm in [aggregation-spec.md](aggregation-spec.md) or a documented compatible variant -- Issues trust tokens conforming to the token schema -- Publishes public keys at `/.well-known/ttp-keys` -- Implements all error codes defined in Section 15 - -An implementation is a **conformant Verifier** if it: - -- Validates JWT signatures using the Trust Authority public key -- Rejects expired tokens -- Enforces domain scope -- Enforces score thresholds -- Returns rejection responses conforming to Section 9.3 - -An implementation is a **conformant Issuer** if it: - -- Produces receipts conforming to the receipt schema -- Signs receipts using the canonicalization defined in Section 5.3 -- Uses unique `receipt_id` values per receipt -- Submits receipts via the protocol defined in Section 6 - -A Trust Authority is **conformant for peer receipts** (Section 17) if it: - -- Accepts peer receipt submissions at `POST /v1/peer-receipts` -- Validates attester eligibility (score ≥ 0.90, issuer_type registration) -- Calls the confirmation API when configured and fails closed on non-approval -- Applies the reduced 20% issuer weight cap for peer issuers during aggregation - -Conformance test vectors are provided in [test-vectors/](test-vectors/). - ---- - -## 17. Agent-as-Issuer (Peer Receipts) - -### 17.1 Overview - -In multi-agent workflows, agents observe each other's behavior directly. This section defines how a trusted agent can act as a behavioral issuer and submit signed receipts attesting to another agent's conduct. - -A **peer receipt** is a behavioral receipt submitted by a registered agent (not an infrastructure issuer) on behalf of another agent it has directly observed. Peer receipts enable trust propagation across agent networks without requiring human-operated observation infrastructure. - -### 17.2 Eligibility - -An agent MAY be registered as a peer issuer if: - -1. It is explicitly registered by an operator with `issuer_type: "agent_peer"` via the admin API. -2. At receipt submission time, the attesting agent holds a current trust token with `ttp_score >= 0.90` in the target domain. -3. The attesting agent is not blocked. - -A Trust Authority MUST NOT accept peer receipts from agents that do not meet all eligibility requirements at the time of submission. - -### 17.3 Peer Receipt Submission - -Peer receipts are submitted via a dedicated endpoint: - -``` -POST /v1/peer-receipts -``` - -The request body includes the standard behavioral receipt fields plus an `attester_token` field: - -```json -{ - "receipt": { - "ttp_version": "1.0", - "receipt_id": "7f3d9a2b-1e4c-8f6a-...", - "agent_id": "agent-b-456", - "issuer_id": "agent-a-123", - "event_type": "agent_peer_observation", - "event_data": { - "observation_context": "pipeline-step-3", - "behaviors_observed": ["tool_call", "api_request"] - }, - "domain": "retention", - "timestamp": 1700000000000, - "score": 0.93, - "signature": "base64url..." - }, - "attester_token": "eyJhbGciOiJFZERTQSIs..." -} -``` - -The `event_type` for peer receipts MUST be `"agent_peer_observation"`. - -The `attester_token` MUST be a valid, non-expired trust token issued by the Trust Authority for the attesting agent in the same domain as the receipt. - -### 17.4 Trust Authority Validation - -Upon receiving a peer receipt, the Trust Authority MUST: - -1. Verify the receipt structure and all required fields. -2. Verify the receipt event_type is `"agent_peer_observation"`. -3. Verify the receipt signature against the attesting agent's registered public key. -4. Decode the `attester_token` and check it has not expired. -5. Confirm `attester_token.ttp_score >= 0.90` (or the issuer's configured `min_attester_score`). -6. Confirm `attester_token.sub` matches `receipt.issuer_id`. -7. Confirm `receipt.issuer_id` is registered as `issuer_type: "agent_peer"`. -8. If a `confirmation_url` is configured for this peer issuer, call the Peer Receipt Confirmation API (§17.5). A non-approved response MUST cause the receipt to be rejected. - -Steps 1–7 are mandatory. Step 8 is conditional on operator configuration. - -### 17.5 Peer Receipt Confirmation API - -Operators MAY configure a `confirmation_url` per peer issuer. When configured, the Trust Authority POSTs a confirmation request before accepting any peer receipt — **no means no**. - -**Request (POST to `confirmation_url`):** -```json -{ - "receipt_id": "7f3d9a2b-...", - "attesting_agent_id": "agent-a-123", - "subject_agent_id": "agent-b-456", - "score": 0.93, - "domain": "retention", - "observation_context": "pipeline-step-3", - "attester_score": 0.94, - "timestamp": 1700000000000 -} -``` - -**Approved response (200 OK):** -```json -{ "approved": true } -``` - -**Denied response (200 OK with `approved: false`, or any non-200):** -```json -{ "approved": false, "reason": "score_inconsistent_with_known_behavior" } -``` - -The Trust Authority MUST: -- Complete the confirmation API call within **2 seconds**. -- On timeout, treat as `approved: false` (fail closed). -- On DNS or network failure, treat as `approved: false` (fail closed). -- NEVER retry a denied confirmation for the same receipt. -- Return `PEER_CONFIRMATION_DENIED` with the external reason in the response. - -### 17.6 Peer Receipt Weight Cap - -Peer receipts are subject to a reduced issuer weight cap in the aggregation algorithm: - -| Issuer Type | Max Issuer Weight | -|-------------|-------------------| -| `infrastructure` | 0.40 (40%) | -| `agent_peer` | 0.20 (20%) | - -This cap ensures that no single peer attester can dominate an agent's trust score, even when submitting many receipts. The reduced cap limits coordinated manipulation risk in agent networks. - -### 17.7 Peer Issuer Registration - -Peer issuers are registered via the admin API: - -``` -POST /v1/admin/issuers -Authorization: Bearer - -{ - "issuer_id": "agent-a-123", - "issuer_type": "agent_peer", - "public_key": "base64url-encoded-ed25519-public-key", - "domain": "retention", - "peer_agent_id": "agent-a-123", - "confirmation_url": "https://confirmation.internal/peer-confirm", - "min_attester_score": 0.90, - "description": "Agent A peer attestation" -} -``` - -| Field | Required | Description | -|-------|----------|-------------| -| `issuer_type` | Yes | Must be `"agent_peer"` | -| `peer_agent_id` | Yes | `agent_id` of the attesting agent. MUST match a registered agent. | -| `confirmation_url` | No | External confirmation gate URL. If omitted, only internal eligibility checks apply. | -| `min_attester_score` | No | Minimum attester score (default: 0.90). | - -The `issuer_id` SHOULD be identical to `peer_agent_id` — the agent and the issuer share the same identity. - -### 17.8 Attester Accountability - -When peer receipts are later contradicted by infrastructure issuer receipts, operators SHOULD investigate the discrepancy and MAY: - -- Revoke the peer issuer's registration. -- Submit a low-score receipt for the attesting agent via a safety monitor issuer. -- Reduce `min_attester_score` or add a confirmation gate. - -Peer issuers whose attestations consistently agree with infrastructure observations MAY be considered for elevated trust by operators, but the protocol does not define automatic promotion — this is an operator policy decision. - ---- - ---- - -## 18. Quarantine and Trust Provisioning - -### 18.1 Agent States - -Every agent tracked by the Trust Authority exists in one of three states: - -| State | Description | Token Issuance | -|-------|-------------|----------------| -| `active` | Normal operation | Standard TTL (≤600s) | -| `quarantined` | Restricted access; token carries `ttp_quarantined: true` | Reduced TTL (≤60s) | -| `blocked` | Hard deny | Rejected with 403 `AGENT_BLOCKED` | - -State transitions: - -``` -active ──────────────────────────────────────────► quarantined (auto) - ↑ score < AUTO_QUARANTINE_THRESHOLD (0.35) │ - │ score ≥ AUTO_LIFT_THRESHOLD (0.65) │ - └──────────────────────────────────────────────────┘ - -active ──── admin action ────────────────────────► quarantined (manual | supervised) -quarantined (manual | supervised) ── admin action ──► active - -any state ── admin action ──────────────────────────► blocked -``` - -Auto-quarantine is triggered and resolved automatically during token issuance, based on the aggregated score. Manual and supervised quarantines persist until an administrator explicitly lifts them. - -### 18.2 Quarantine Modes - -| Mode | Triggered By | Lifted By | -|------|--------------|-----------| -| `auto` | Trust Authority — score fell below threshold | Trust Authority — score recovered above threshold | -| `manual` | Administrator | Administrator only | -| `supervised` | Administrator — marks human review required | Administrator after review | - -### 18.3 Auto-Quarantine Thresholds - -| Threshold | Value | Description | -|-----------|-------|-------------| -| `AUTO_QUARANTINE_THRESHOLD` | 0.35 | Score below this triggers auto-quarantine | -| `AUTO_LIFT_THRESHOLD` | 0.65 | Score above this lifts auto-quarantine | - -These values are RECOMMENDED defaults. Operators MAY configure different thresholds per domain via the Trust Authority configuration. - -The auto-quarantine check runs during every token issuance: - -``` -score = aggregate(receipts) -if agent.status == "active" AND score < 0.35: - quarantine(agent, mode="auto") -if agent.status == "quarantined" AND agent.quarantine_mode == "auto" AND score >= 0.65: - lift_quarantine(agent) -``` - -### 18.4 Quarantine Token Claims - -When a Trust Authority issues a token for a quarantined agent, it MUST include: - -```json -{ - "ttp_quarantined": true, - "ttp_quarantine_mode": "auto" -} -``` - -The Trust Authority MUST reduce the token TTL to a maximum of **60 seconds** for quarantined agents. The reduced TTL ensures trust recovery propagates quickly — within one minute of the agent's score recovering above the lift threshold, the next token will reflect the restored status. - -### 18.5 Quarantine HTTP Endpoints - -**Quarantine an agent (manual):** -``` -POST /v1/admin/agents/:agentId/quarantine -Authorization: Bearer - -{ - "reason": "Repeated boundary violations in CRM domain", - "mode": "supervised", - "duration_s": 86400 -} -``` - -`duration_s` is OPTIONAL. If omitted, quarantine persists until explicitly lifted. - -**Lift quarantine:** -``` -POST /v1/admin/agents/:agentId/lift-quarantine -Authorization: Bearer -``` - -**Get agent status:** -``` -GET /v1/admin/agents/:agentId/status -Authorization: Bearer -``` - -Response: -```json -{ - "agent_id": "agent-prod-abc123", - "status": "quarantined", - "registered_at": 1700000000000, - "quarantine": { - "mode": "supervised", - "reason": "Repeated boundary violations in CRM domain", - "quarantined_at": 1700001000000, - "expires_at": 1700087400000 - } -} -``` - -### 18.6 Verifier Behavior for Quarantined Agents - -Verifiers MUST expose the quarantine state to operators. The RECOMMENDED behavior: - -- **Default**: Allow quarantined agents through if their score meets the threshold (with quarantine status visible on `req.ttp.quarantined`). Operators should log quarantined access for audit. -- **`denyQuarantined: true`**: Reject quarantined agents with 403 `AGENT_QUARANTINED` regardless of score. Appropriate for high-security endpoints. - -```typescript -// Allow quarantined agents through, but log them -app.post("/api/send-notification", - createTTPMiddleware({ domain: "retention", minScore: 0.70, authorityPublicKey }), - (req, res) => { - if (req.ttp!.quarantined) { - auditLog.warn("Quarantined agent accessing endpoint", { - agentId: req.ttp!.agentId, - quarantineMode: req.ttp!.quarantineMode - }) - } - // ... proceed - } -) - -// Block quarantined agents entirely -app.post("/api/issue-discount", - createTTPMiddleware({ - domain: "retention", - minScore: 0.85, - authorityPublicKey, - denyQuarantined: true // §18 hard gate for high-value actions - }), - handler -) -``` - -### 18.7 Trust Provisioning - -Trust provisioning allows operators to assign a baseline trust score to an agent before it has earned behavioral receipts. Primary use cases: - -- **Cold-start bootstrap**: New agents that need to operate immediately before behavioral history accumulates. -- **Recovery assistance**: Post-quarantine recovery where an agent needs a modest trust boost to start earning receipts again. -- **Role-based baseline**: Certain agent roles (auditors, monitors) should start with a trusted baseline appropriate to their function. - -### 18.8 Provisioning Mechanism - -Provisioning creates synthetic behavioral receipts issued by the Trust Authority itself via a built-in issuer: `ttp-authority-provisioned`. - -``` -POST /v1/admin/agents/:agentId/provision-trust -Authorization: Bearer - -{ - "domain": "retention", - "score": 0.80, - "duration_s": 3600, - "reason": "Cold-start bootstrap for agent-prod-new" -} -``` - -Response: -```json -{ - "status": "provisioned", - "grant_id": "7f3d9a2b-...", - "agent_id": "agent-prod-new", - "domain": "retention", - "score": 0.80, - "duration_s": 3600, - "receipt_ids": ["...", "...", "..."] -} -``` - -The Trust Authority creates multiple synthetic receipts staggered across the receipt window for stable aggregation. These receipts have `event_type: "authority_provisioned"` and expire naturally as they age out of the receipt window. - -### 18.9 Provisioned Trust Weight Cap - -The `ttp-authority-provisioned` issuer is subject to a **30% weight cap** (between infrastructure at 40% and peer at 20%): - -| Issuer Type | Max Issuer Weight | -|-------------|-------------------| -| `infrastructure` | 0.40 (40%) | -| `ttp-authority-provisioned` | 0.30 (30%) | -| `agent_peer` | 0.20 (20%) | - -This ensures provisioned trust cannot dominate the aggregated score — once behavioral receipts accumulate, they progressively outweigh the provisioned baseline. - -### 18.10 Provisioning Constraints - -- `score` MUST be in [0.0, 1.0]. -- `duration_s` MUST be between 1 and 604800 (7 days). -- Provisioned receipts have `event_type: "authority_provisioned"` and are distinguishable in audit logs. -- Operators SHOULD NOT provision scores above 0.85 — this would grant high-security action access before behavioral evidence accumulates. -- Provisioned trust is not a substitute for real behavioral receipts. Operators SHOULD treat it as scaffolding while issuers come online. - ---- - -*Trust Transfer Protocol Specification v1.0* -*Copyright 2026 BlockSiFr. Licensed under Apache 2.0.* +- [`../README.md`](../README.md) +- [`../SPECIFICATION.md`](../SPECIFICATION.md) +- [`../MVP.md`](../MVP.md) +- [`../THREAT_MODEL.md`](../THREAT_MODEL.md) diff --git a/src/ast.js b/src/ast.js new file mode 100644 index 0000000..ff20379 --- /dev/null +++ b/src/ast.js @@ -0,0 +1,21 @@ +export function createAst() { + return { + subjects: [], + trustClaims: [], + proofs: [], + authorityContexts: [], + delegations: [] + }; +} + +export function findSubject(ast, subjectId) { + return ast.subjects.find((subject) => subject.id === subjectId); +} + +export function findTrustClaim(ast, subjectId) { + return ast.trustClaims.find((claim) => claim.subject === subjectId); +} + +export function findProof(ast, subjectId) { + return ast.proofs.find((proof) => proof.subject === subjectId); +} diff --git a/src/error.js b/src/error.js new file mode 100644 index 0000000..d9fec1a --- /dev/null +++ b/src/error.js @@ -0,0 +1,18 @@ +export class TtpError extends Error { + constructor(code, message) { + super(message); + this.name = "TtpError"; + this.code = code; + } +} + +export function toCliError(error) { + if (error instanceof TtpError) { + return { error: error.code, message: error.message }; + } + + return { + error: "UNEXPECTED_ERROR", + message: error instanceof Error ? error.message : String(error) + }; +} diff --git a/src/evaluator.js b/src/evaluator.js new file mode 100644 index 0000000..71e785b --- /dev/null +++ b/src/evaluator.js @@ -0,0 +1,155 @@ +import { findProof, findSubject, findTrustClaim } from "./ast.js"; +import { TtpError } from "./error.js"; + +export function evaluate(ast, { subject, at = "now" }) { + const evaluatedAt = parseEvaluationTime(at); + const subjectModel = findSubject(ast, subject); + if (!subjectModel) { + throw new TtpError("MISSING_SUBJECT", `Subject not found: ${subject}`); + } + + const claim = findTrustClaim(ast, subject); + if (!claim) { + throw new TtpError("MISSING_TRUST", `Trust claim not found for subject: ${subject}`); + } + + const proof = findProof(ast, subject); + if (!proof) { + throw new TtpError("MISSING_PROOF", `Proof not found for subject: ${subject}`); + } + + if (proof.mode !== "cleartext-dev") { + throw new TtpError("UNSUPPORTED_PROOF_MODE", `Unsupported proof mode: ${proof.mode}`); + } + + const expiresAt = parseDate(claim.expires_at, "expires_at"); + if (evaluatedAt > expiresAt) { + return result({ + subject, + effectiveScore: 0, + requiredScore: proof.required_score, + outcome: "TRUST_PROOF_EXPIRED", + reason: "trust claim expired before evaluation", + proofMode: proof.mode, + evaluatedAt, + expiresAt + }); + } + + if (proof.freshness) { + const issuedAt = parseDate(claim.issued_at, "issued_at"); + const maxAgeMs = parseDuration(proof.freshness); + if (evaluatedAt.getTime() - issuedAt.getTime() > maxAgeMs) { + return result({ + subject, + effectiveScore: 0, + requiredScore: proof.required_score, + outcome: "TRUST_PROOF_EXPIRED", + reason: "trust proof is older than required freshness", + proofMode: proof.mode, + evaluatedAt, + expiresAt + }); + } + } + + const effectiveScore = calculateEffectiveScore(claim, evaluatedAt); + const requiredScore = Number(proof.required_score); + + if (effectiveScore >= requiredScore) { + return result({ + subject, + effectiveScore, + requiredScore, + outcome: "TRUST_PROOF_VALID", + reason: "effective trust score meets threshold", + proofMode: proof.mode, + evaluatedAt, + expiresAt + }); + } + + return result({ + subject, + effectiveScore, + requiredScore, + outcome: "TRUST_PROOF_INSUFFICIENT", + reason: "effective trust score is below threshold", + proofMode: proof.mode, + evaluatedAt, + expiresAt + }); +} + +export function calculateEffectiveScore(claim, evaluatedAt) { + const score = Number(claim.score); + if (!claim.decay) { + return roundScore(score); + } + + if (claim.decay.model !== "linear") { + throw new TtpError("UNSUPPORTED_DECAY_MODEL", `Unsupported decay model: ${claim.decay.model}`); + } + + const issuedAt = parseDate(claim.issued_at, "issued_at"); + const elapsedMs = Math.max(0, evaluatedAt.getTime() - issuedAt.getTime()); + const halfLifeMs = parseDuration(claim.decay.half_life); + const minimum = Number(claim.decay.minimum ?? 0); + const periods = elapsedMs / halfLifeMs; + const decayed = minimum + (score - minimum) * Math.pow(0.5, periods); + + return roundScore(Math.max(minimum, Math.min(score, decayed))); +} + +export function parseDuration(duration) { + const match = /^(\d+(?:\.\d+)?)(ms|s|m|h|d)$/.exec(String(duration)); + if (!match) { + throw new TtpError("SYNTAX_ERROR", `Invalid duration: ${duration}`); + } + + const value = Number(match[1]); + const unit = match[2]; + const multipliers = { + ms: 1, + s: 1000, + m: 60 * 1000, + h: 60 * 60 * 1000, + d: 24 * 60 * 60 * 1000 + }; + + return value * multipliers[unit]; +} + +function parseEvaluationTime(at) { + if (at === "now") { + return new Date(); + } + + return parseDate(at, "at"); +} + +function parseDate(value, field) { + const date = new Date(value); + if (Number.isNaN(date.getTime())) { + throw new TtpError("SYNTAX_ERROR", `Invalid ${field} timestamp: ${value}`); + } + return date; +} + +function roundScore(score) { + return Math.round(score * 10000) / 10000; +} + +function result({ subject, effectiveScore, requiredScore, outcome, reason, proofMode, evaluatedAt, expiresAt }) { + return { + subject, + effective_score: roundScore(effectiveScore), + required_score: roundScore(requiredScore), + result: outcome, + reason, + proof_mode: proofMode, + evaluated_at: evaluatedAt.toISOString(), + expires_at: expiresAt.toISOString(), + receipt_hash_optional: null + }; +} diff --git a/src/index.js b/src/index.js new file mode 100755 index 0000000..045fcea --- /dev/null +++ b/src/index.js @@ -0,0 +1,73 @@ +#!/usr/bin/env node +import { checkFile, evalFile } from "./lib.js"; +import { toCliError, TtpError } from "./error.js"; + +const VERSION = "0.1.0-mvp"; + +export async function runCli(argv, io = console) { + const [command, ...args] = argv; + + if (!command || command === "help" || command === "--help" || command === "-h") { + io.log(helpText()); + return 0; + } + + if (command === "version" || command === "--version" || command === "-v") { + io.log(`ttp ${VERSION}`); + return 0; + } + + if (command === "check") { + const file = args[0]; + if (!file) { + throw new TtpError("INVALID_ARGUMENT", "Usage: ttp check "); + } + io.log(JSON.stringify(await checkFile(file), null, 2)); + return 0; + } + + if (command === "eval") { + const file = args[0]; + if (!file) { + throw new TtpError("INVALID_ARGUMENT", "Usage: ttp eval --subject --at "); + } + + const subject = readFlag(args, "--subject"); + if (!subject) { + throw new TtpError("INVALID_ARGUMENT", "ttp eval requires --subject "); + } + + const at = readFlag(args, "--at") ?? "now"; + io.log(JSON.stringify(await evalFile(file, { subject, at }), null, 2)); + return 0; + } + + throw new TtpError("INVALID_ARGUMENT", `Unknown command: ${command}`); +} + +function readFlag(args, flag) { + const index = args.indexOf(flag); + if (index === -1) { + return null; + } + return args[index + 1] ?? null; +} + +function helpText() { + return `Trust Transfer Protocol CLI + +Usage: + ttp check + ttp eval --subject --at + ttp version +`; +} + +if (import.meta.url === `file://${process.argv[1]}`) { + runCli(process.argv.slice(2)).then((code) => { + process.exitCode = code; + }).catch((error) => { + console.error(JSON.stringify(toCliError(error), null, 2)); + process.exitCode = 1; + }); +} diff --git a/src/lib.js b/src/lib.js new file mode 100644 index 0000000..fc58b69 --- /dev/null +++ b/src/lib.js @@ -0,0 +1,39 @@ +import { readFile } from "node:fs/promises"; +import { parseTtp } from "./parser.js"; +import { evaluate } from "./evaluator.js"; +import { TtpError } from "./error.js"; + +export { parseTtp } from "./parser.js"; +export { evaluate, calculateEffectiveScore, parseDuration } from "./evaluator.js"; +export { TtpError } from "./error.js"; + +export async function loadTtpFile(filePath) { + try { + return await readFile(filePath, "utf8"); + } catch (error) { + if (error && error.code === "ENOENT") { + throw new TtpError("FILE_NOT_FOUND", `File not found: ${filePath}`); + } + throw error; + } +} + +export async function checkFile(filePath) { + const source = await loadTtpFile(filePath); + const ast = parseTtp(source); + return { + ok: true, + file: filePath, + subjects: ast.subjects.length, + trust_claims: ast.trustClaims.length, + proofs: ast.proofs.length, + authority_contexts: ast.authorityContexts.length, + delegations: ast.delegations.length + }; +} + +export async function evalFile(filePath, options) { + const source = await loadTtpFile(filePath); + const ast = parseTtp(source); + return evaluate(ast, options); +} diff --git a/src/parser.js b/src/parser.js new file mode 100644 index 0000000..3aed750 --- /dev/null +++ b/src/parser.js @@ -0,0 +1,200 @@ +import { createAst } from "./ast.js"; +import { TtpError } from "./error.js"; + +const TOP_LEVEL_BLOCKS = new Set([ + "subject", + "trust", + "proof", + "authority_context", + "delegation" +]); + +export function parseTtp(source) { + const ast = createAst(); + const blocks = parseBlocks(source); + + for (const block of blocks) { + const fields = parseFields(block.body); + + if (block.type === "subject") { + ast.subjects.push({ id: block.name, ...fields }); + } else if (block.type === "trust") { + ast.trustClaims.push({ subject: block.name, ...fields }); + } else if (block.type === "proof") { + ast.proofs.push({ id: block.name, ...fields }); + } else if (block.type === "authority_context") { + ast.authorityContexts.push({ id: block.name, ...fields }); + } else if (block.type === "delegation") { + ast.delegations.push({ id: block.name, ...fields }); + } + } + + validateAst(ast); + return ast; +} + +function parseBlocks(source) { + const blocks = []; + let index = 0; + const blockPattern = /\b(subject|trust|proof|authority_context|delegation)\s+"([^"]+)"\s*\{/g; + + while (index < source.length) { + blockPattern.lastIndex = index; + const match = blockPattern.exec(source); + if (!match) { + const trailing = source.slice(index).replace(/\/\/.*$/gm, "").trim(); + if (trailing) { + throw new TtpError("SYNTAX_ERROR", `Unexpected content near: ${trailing.slice(0, 40)}`); + } + break; + } + + const type = match[1]; + const name = match[2]; + if (!TOP_LEVEL_BLOCKS.has(type)) { + throw new TtpError("SYNTAX_ERROR", `Unsupported block type: ${type}`); + } + + const bodyStart = match.index + match[0].length; + const bodyEnd = findMatchingBrace(source, bodyStart - 1); + blocks.push({ + type, + name, + body: source.slice(bodyStart, bodyEnd) + }); + index = bodyEnd + 1; + } + + return blocks; +} + +function findMatchingBrace(source, openBraceIndex) { + let depth = 0; + let inString = false; + + for (let i = openBraceIndex; i < source.length; i += 1) { + const char = source[i]; + const previous = source[i - 1]; + + if (char === "\"" && previous !== "\\") { + inString = !inString; + } + + if (inString) { + continue; + } + + if (char === "{") { + depth += 1; + } else if (char === "}") { + depth -= 1; + if (depth === 0) { + return i; + } + } + } + + throw new TtpError("SYNTAX_ERROR", "Unclosed block"); +} + +function parseFields(body) { + const fields = {}; + let remaining = body; + + const decayMatch = /\bdecay\s*\{([\s\S]*?)\}/m.exec(remaining); + if (decayMatch) { + fields.decay = parseFields(decayMatch[1]); + remaining = remaining.replace(decayMatch[0], ""); + } + + const arrayPattern = /^(\s*)([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*\[([\s\S]*?)\]/gm; + remaining = remaining.replace(arrayPattern, (_match, _space, key, values) => { + fields[key] = [...values.matchAll(/"([^"]+)"/g)].map((value) => value[1]); + return ""; + }); + + const scalarPattern = /^\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*=\s*(.+?)\s*$/gm; + let scalarMatch; + while ((scalarMatch = scalarPattern.exec(remaining)) !== null) { + fields[scalarMatch[1]] = parseValue(scalarMatch[2]); + } + + const leftovers = remaining + .replace(scalarPattern, "") + .replace(/\/\/.*$/gm, "") + .trim(); + + if (leftovers) { + throw new TtpError("SYNTAX_ERROR", `Could not parse field content: ${leftovers.slice(0, 60)}`); + } + + return fields; +} + +function parseValue(rawValue) { + const value = rawValue.trim().replace(/,$/, ""); + + if (value.startsWith("\"") && value.endsWith("\"")) { + return value.slice(1, -1); + } + + if (/^-?\d+(\.\d+)?$/.test(value)) { + return Number(value); + } + + if (/^proof\.[a-zA-Z_][a-zA-Z0-9_]*$/.test(value)) { + return value; + } + + if (value === "true") { + return true; + } + + if (value === "false") { + return false; + } + + throw new TtpError("SYNTAX_ERROR", `Unsupported value: ${value}`); +} + +function validateAst(ast) { + if (ast.subjects.length === 0) { + throw new TtpError("MISSING_SUBJECT", "At least one subject block is required"); + } + + if (ast.trustClaims.length === 0) { + throw new TtpError("MISSING_TRUST", "At least one trust block is required"); + } + + if (ast.proofs.length === 0) { + throw new TtpError("MISSING_PROOF", "At least one proof block is required"); + } + + for (const claim of ast.trustClaims) { + if (!ast.subjects.some((subject) => subject.id === claim.subject)) { + throw new TtpError("INVALID_REFERENCE", `Trust block references unknown subject: ${claim.subject}`); + } + requireFields(claim, ["issuer", "score", "issued_at", "expires_at"], "trust"); + } + + for (const proof of ast.proofs) { + requireFields(proof, ["subject", "required_score", "mode"], "proof"); + if (!ast.subjects.some((subject) => subject.id === proof.subject)) { + throw new TtpError("INVALID_REFERENCE", `Proof references unknown subject: ${proof.subject}`); + } + } + + for (const context of ast.authorityContexts) { + if (context.requires && !ast.proofs.some((proof) => `proof.${proof.id}` === context.requires)) { + throw new TtpError("INVALID_REFERENCE", `Authority context references unknown proof: ${context.requires}`); + } + } +} + +function requireFields(object, fields, blockType) { + for (const field of fields) { + if (object[field] === undefined || object[field] === null || object[field] === "") { + throw new TtpError("SYNTAX_ERROR", `${blockType} block is missing required field: ${field}`); + } + } +} diff --git a/tests/ttp-cli.test.mjs b/tests/ttp-cli.test.mjs new file mode 100644 index 0000000..0f7dd0f --- /dev/null +++ b/tests/ttp-cli.test.mjs @@ -0,0 +1,93 @@ +import assert from "node:assert/strict"; +import { mkdtemp, writeFile } from "node:fs/promises"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import test from "node:test"; + +import { checkFile, evalFile } from "../src/lib.js"; +import { parseTtp } from "../src/parser.js"; +import { TtpError } from "../src/error.js"; +import { runCli } from "../src/index.js"; + +test("valid basic example parses", async () => { + const result = await checkFile("examples/01-basic-agent.ttp"); + + assert.equal(result.ok, true); + assert.equal(result.subjects, 1); + assert.equal(result.trust_claims, 1); + assert.equal(result.proofs, 1); +}); + +test("missing subject fails", () => { + assert.throws( + () => parseTtp(` +trust "agent:missing" { + issuer = "verifiedtrust:tenant_123" + score = 0.9 + issued_at = "2026-05-11T12:00:00Z" + expires_at = "2026-05-11T13:00:00Z" +} + +proof "p" { + subject = "agent:missing" + required_score = 0.7 + mode = "cleartext-dev" +} +`), + (error) => error instanceof TtpError && error.code === "MISSING_SUBJECT" + ); +}); + +test("expired trust fails evaluation", async () => { + const result = await evalFile("examples/01-basic-agent.ttp", { + subject: "agent:invoice_reviewer", + at: "2026-05-11T19:00:00Z" + }); + + assert.equal(result.result, "TRUST_PROOF_EXPIRED"); +}); + +test("decayed trust below threshold fails", async () => { + const result = await evalFile("examples/02-trust-decay.ttp", { + subject: "agent:invoice_reviewer", + at: "2026-05-11T19:30:00Z" + }); + + assert.equal(result.result, "TRUST_PROOF_INSUFFICIENT"); + assert.ok(result.effective_score < result.required_score); +}); + +test("threshold met returns valid evaluation", async () => { + const result = await evalFile("examples/01-basic-agent.ttp", { + subject: "agent:invoice_reviewer", + at: "2026-05-11T12:30:00Z" + }); + + assert.equal(result.result, "TRUST_PROOF_VALID"); + assert.ok(result.effective_score >= result.required_score); +}); + +test("CLI check returns success for examples", async () => { + const output = []; + const code = await runCli(["check", "examples/01-basic-agent.ttp"], { + log: (line) => output.push(line), + error: (line) => output.push(line) + }); + const result = JSON.parse(output.join("\n")); + + assert.equal(code, 0); + assert.equal(result.ok, true); +}); + +test("invalid syntax returns useful errors", async () => { + const dir = await mkdtemp(join(tmpdir(), "ttp-test-")); + const fixture = join(dir, "invalid.ttp"); + await writeFile(fixture, `subject "agent:broken" {\n type = "ai_agent"\n`, "utf8"); + + await assert.rejects( + () => runCli(["check", fixture], { log: () => {}, error: () => {} }), + (error) => { + return error instanceof TtpError && error.code === "SYNTAX_ERROR" && /Unclosed block/.test(error.message); + } + ); +});