From ff5c48fd359aaed190f7bcf60ec3ffbb7bda7ab7 Mon Sep 17 00:00:00 2001 From: blocksifrdev Date: Thu, 23 Apr 2026 15:46:46 -0400 Subject: [PATCH 1/2] Add single governed execution workflow --- .github/workflows/governed-execution.yml | 131 +++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 .github/workflows/governed-execution.yml diff --git a/.github/workflows/governed-execution.yml b/.github/workflows/governed-execution.yml new file mode 100644 index 0000000..ccebbe9 --- /dev/null +++ b/.github/workflows/governed-execution.yml @@ -0,0 +1,131 @@ +name: TTP / Governed Execution Proof + +on: + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + +jobs: + govern: + name: Governed Execution + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + + outputs: + decision: ${{ steps.authorize.outputs.decision }} + receipt: ${{ steps.authorize.outputs.receipt }} + + steps: + # 1️⃣ Full checkout (safe and correct) + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + # 2️⃣ Detect changed files + - name: Detect changes + id: changes + shell: bash + run: | + set -euo pipefail + BASE="${{ github.event.pull_request.base.sha }}" + HEAD="${{ github.event.pull_request.head.sha }}" + + git diff --name-only "$BASE" "$HEAD" > changed.txt || true + + echo "Changed files:" + cat changed.txt || true + + PATHS_JSON=$(jq -R . < changed.txt | jq -s .) + echo "paths=$PATHS_JSON" >> "$GITHUB_OUTPUT" + + # 3️⃣ Ask external authority for permission + - name: Authorize execution + id: authorize + env: + AUTH_URL: ${{ secrets.RUNTIME_AUTH_URL }} + AUTH_TOKEN: ${{ secrets.RUNTIME_AUTH_TOKEN }} + shell: bash + run: | + set -euo pipefail + + if [ ! -s changed.txt ]; then + echo "No changes → deny by policy" + echo "decision=DENY" >> "$GITHUB_OUTPUT" + echo "receipt=" >> "$GITHUB_OUTPUT" + exit 0 + fi + + jq -n \ + --arg repo "${{ github.repository }}" \ + --arg actor "${{ github.actor }}" \ + --arg pr "${{ github.event.pull_request.number }}" \ + --arg sha "${{ github.event.pull_request.head.sha }}" \ + --argjson paths "$(jq -s . changed.txt | jq -R .)" \ + '{ + subject: "wi://github/actions/runner", + action: "pull_request.execute", + resource: ("repo:" + $repo + ":pr/" + $pr), + commitSha: $sha, + actor: $actor, + pathsTouched: $paths, + context: { + event: "pull_request", + repo: $repo + } + }' > request.json + + curl -sS \ + -H "Authorization: Bearer $AUTH_TOKEN" \ + -H "Content-Type: application/json" \ + -X POST "$AUTH_URL/re/authorize" \ + -d @request.json \ + > response.json + + cat response.json + + DECISION=$(jq -r '.decision // "DENY"' response.json) + RECEIPT=$(jq -r '.receiptId // ""' response.json) + + echo "decision=$DECISION" >> "$GITHUB_OUTPUT" + echo "receipt=$RECEIPT" >> "$GITHUB_OUTPUT" + + # 4️⃣ Human approval if required + step-up: + name: Step‑Up Approval + runs-on: ubuntu-latest + needs: govern + if: needs.govern.outputs.decision == 'STEP_UP' + environment: + name: protected-execution + steps: + - run: | + echo "Manual authorization granted via environment." + echo "Receipt: ${{ needs.govern.outputs.receipt }}" + + # 5️⃣ Final enforcement gate + enforce: + name: Enforce Authority Decision + runs-on: ubuntu-latest + needs: [govern, step-up] + if: always() + steps: + - run: | + DECISION="${{ needs.govern.outputs.decision }}" + RECEIPT="${{ needs.govern.outputs.receipt }}" + + echo "Final decision: $DECISION" + echo "Receipt: $RECEIPT" + + if [ -z "$RECEIPT" ]; then + echo "Missing receipt → hard deny" + exit 1 + fi + + if [ "$DECISION" = "PERMIT" ]; then + echo "✅ Execution permitted" + exit 0 + fi + + echo "❌ Execution denied" + exit 1 From 4a5ec5f2cc944934e14c6551dae3f81a7473352e Mon Sep 17 00:00:00 2001 From: blocksifrdev Date: Mon, 11 May 2026 09:55:14 -0400 Subject: [PATCH 2/2] Improve adoption quickstart and demo --- .../ISSUE_TEMPLATE/quickstart-feedback.yml | 39 ++++++ .github/workflows/ci.yml | 24 ++++ README.md | 119 +++++++++++------- docs/getting-started.md | 55 +++++--- docs/integration-guide.md | 29 +++-- docs/public-readiness.md | 29 +++-- examples/basic-agent/index.ts | 8 +- examples/local-trust-gate-demo.mjs | 117 +++++++++++++++++ package.json | 1 + 9 files changed, 342 insertions(+), 79 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/quickstart-feedback.yml create mode 100644 .github/workflows/ci.yml create mode 100644 examples/local-trust-gate-demo.mjs diff --git a/.github/ISSUE_TEMPLATE/quickstart-feedback.yml b/.github/ISSUE_TEMPLATE/quickstart-feedback.yml new file mode 100644 index 0000000..45d548a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/quickstart-feedback.yml @@ -0,0 +1,39 @@ +name: Quickstart feedback +description: Report friction from the first TTP demo or integration path. +title: "[Quickstart]: " +labels: + - docs + - developer-experience +body: + - type: markdown + attributes: + value: | + Use this when the local demo, getting started guide, or first integration path is unclear or does not work. + - type: input + id: path + attributes: + label: Path tried + description: Which path were you using? + placeholder: npm run demo, SDK install, Trust Authority setup, GitHub Actions gate + validations: + required: true + - type: textarea + id: expected + attributes: + label: Expected outcome + description: What did you expect to happen? + validations: + required: true + - type: textarea + id: actual + attributes: + label: Actual outcome + description: What happened instead? Include command output if useful. + validations: + required: true + - type: textarea + id: environment + attributes: + label: Environment + description: Node version, OS, package manager, and any relevant runtime context. + placeholder: Node 20, macOS/Linux/Windows, npm/pnpm/yarn diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..2a2b77f --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,24 @@ +name: CI + +on: + pull_request: + push: + branches: + - main + +jobs: + verify: + name: Demo and Tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: 20 + + - name: Run local adoption demo + run: npm run demo + + - name: Run trust-routing tests + run: npm run test:trust-routing diff --git a/README.md b/README.md index 0b5a7fd..e842c27 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ # Trust Transfer Protocol (TTP) -TTP is an open protocol for runtime trust verification of autonomous systems using signed behavioral evidence and short-lived trust tokens. -It solves the gap between **identity authentication** and **execution-time trustworthiness**. +TTP is an open protocol for deciding whether an autonomous system should be allowed to execute a protected action right now. + +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. [![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) @@ -9,22 +10,57 @@ It solves the gap between **identity authentication** and **execution-time trust --- -## If you only read one section +## Why Teams Adopt TTP + +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. + +Instead of asking only "who is calling?", TTP asks: + +```text +Should this subject execute this action on this resource now? +``` -TTP adds a trust check before execution. Issuers publish signed behavioral receipts, a Trust Authority aggregates them into a short-lived trust token, and services verify that token at the moment of action. The decision is scoped, time-bounded, and cryptographically verifiable; if trust requirements are not met, execution is denied or constrained. +The answer is explicit: `PERMIT`, `DENY`, `STEP_UP`, `THROTTLE`, or `CONSTRAIN`, with a receipt that can be audited later. --- -## What this is / What this is not +## 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: + +```text +PERMIT trusted build action +decision: PERMIT +reason: route_valid + +STEP_UP production deploy +decision: STEP_UP +reason: step_up_required + +DENY revoked workload +decision: DENY +reason: revoked_subject +``` + +The demo is implemented in `examples/local-trust-gate-demo.mjs` and uses the routing engine in `packages/trust-routing-engine`. + +--- -### What TTP is +## 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 +## What TTP Is Not - Not a replacement for OAuth/OIDC, IAM, SPIFFE, mTLS, ZTNA, or API gateways. - Not a generic monitoring dashboard. @@ -33,29 +69,20 @@ TTP adds a trust check before execution. Issuers publish signed behavioral recei --- -## Why this exists - -Most security controls answer: **who is calling**. -TTP answers: **should this action run now, given recent behavior**. - -Static credentials can remain valid while an agent is compromised, manipulated, or drifting. -TTP addresses that by making trust time-bounded and behavior-derived. - ---- - -## Minimal example (end-to-end) +## Core Flow ```text -Agent -> Trust Token -> Service -> Execute or Deny +execution request -> route resolution -> authority decision -> execution receipt -> enforcement ``` Concrete flow: -1. Agent actions are observed by issuers. -2. Issuers submit signed receipts. -3. Trust Authority computes trust score and issues short-lived token. -4. Service verifies token (signature, freshness, domain, minScore). -5. Service executes or denies. +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. --- @@ -91,16 +118,17 @@ Verification at the service boundary is stateless and cryptographic. ----- -## Trust Routing Subsystem (New) +## Trust Routing Subsystem -TTP now includes a runtime **Trust Routing** subsystem for trust-before-execution: +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/trust-routing-governed-steps.yml` (GitHub Actions wedge demo) +- `.github/workflows/governed-execution.yml` (GitHub Actions governed execution example) +- `examples/local-trust-gate-demo.mjs` (local permit/step-up/deny demo) ----- @@ -628,7 +656,8 @@ Key implementation entry points: - `apps/trust-route-resolver/src/server.mjs` - `packages/trust-routing-engine/src/*` -- `.github/workflows/trust-routing-governed-steps.yml` +- `.github/workflows/governed-execution.yml` +- `examples/local-trust-gate-demo.mjs` --- @@ -647,10 +676,9 @@ ttp-protocol/ │ ├── schemas/ # JSON schemas │ └── rfc/ # Protocol RFCs ├── sdk/ -│ ├── typescript/ # TypeScript SDK -│ ├── python/ # Python SDK -│ └── go/ # Go SDK +│ └── typescript/ # TypeScript SDK foundation ├── examples/ +│ ├── local-trust-gate-demo.mjs │ ├── retention-platform-integration.md │ ├── basic-agent/ │ ├── service-integration/ @@ -666,8 +694,7 @@ ttp-protocol/ │ └── ecosystem-integrations.md ├── reference-implementations/ │ ├── trust-authority/ -│ ├── issuers/ -│ └── verifiers/ +│ └── issuers/ └── README.md ``` @@ -709,11 +736,20 @@ Choose by role: ## Quickstart -### 1) Run Trust Authority reference implementation +### 1) Run the local trust-gate demo + +```bash +npm run demo +``` + +This shows `PERMIT`, `STEP_UP`, and `DENY` decisions with execution receipts. + +### 2) Run Trust Authority reference implementation ```bash cd reference-implementations/trust-authority npm install +npm run build npm run generate-keys npm start ``` @@ -772,21 +808,18 @@ See for guidelines. ## Community -- **Discussions:** [GitHub Discussions](https://github.com/blocksifr/ttp-protocol/discussions) -- **Issues:** [GitHub Issues](https://github.com/blocksifr/ttp-protocol/issues) +- **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) ----- -## Status - -- Guide: `docs/easy-connect-api.md` -- Contract: `runtime/api/connect.contract.md` - -### 3) Integrate full verification flow +## Integration References -- `docs/integration-guide.md` +- Easy connect API: `docs/easy-connect-api.md` +- Runtime connect contract: `runtime/api/connect.contract.md` +- Full verification flow: `docs/integration-guide.md` --- diff --git a/docs/getting-started.md b/docs/getting-started.md index 4fa1608..2adc80e 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -2,31 +2,58 @@ This guide gives a fast path from zero to first protected action, then helps teams choose the right adoption path. -## Quickstart (Simple Path) +## Quickstart: First Trust Gate -1. Run the Trust Authority using the reference implementation. -2. Register one agent and one issuer via admin endpoints. -3. Submit receipts from the issuer as agent actions occur. -4. Request a trust token from the agent. -5. Verify the token in your service and enforce `minScore`. +Run the dependency-free local demo: -Use full commands and setup details in [integration-guide.md](integration-guide.md). +```bash +npm run demo +``` + +The demo shows the core TTP control loop: + +1. A trusted build action receives `PERMIT`. +2. A production deploy receives `STEP_UP`. +3. A revoked workload receives `DENY`. +4. Each decision produces an execution receipt with a chain hash. + +This is the fastest way to see the platform intent: TTP is a runtime trust gate for protected actions, not a replacement for identity, CI, API gateways, or policy engines. + +## Next: Wire A Real Boundary + +After the demo, choose one protected action in your system: + +- a production deploy +- a privileged tool call +- a customer-impacting agent action +- a write operation against sensitive data +- a high-risk workflow step + +Then add TTP at that boundary: + +1. Define the subject, action, resource, and parameter hash. +2. Attach at least one issuer that can observe recent behavior. +3. Resolve the trust route before execution. +4. Enforce `PERMIT`, `DENY`, `STEP_UP`, `THROTTLE`, or `CONSTRAIN`. +5. Store the execution receipt for audit and incident review. + +Use full setup details in [integration-guide.md](integration-guide.md). --- ## Integration Paths (Choose One) -### Path A — Agent Builder +### Path A - Agent Builder - Integrate `TTPClient` in agent runtime. - Request short-lived, domain-scoped trust tokens. - Pass `X-TTP-Token` to protected downstream services. -### Path B — Service/API Owner +### Path B - Service/API Owner - Add TTP middleware or manual verification. - Configure per-route `domain` and `minScore`. - Choose risk-appropriate fallback strategy. -### Path C — Platform/Security Operator +### Path C - Platform/Security Operator - Operate Trust Authority and issuer registry. - Register agents and issuers. - Manage trust thresholds, domain boundaries, and quarantine policy. @@ -37,10 +64,10 @@ Use full commands and setup details in [integration-guide.md](integration-guide. Teams can adopt incrementally: -1. **Network Core Operator** — runs Trust Authority and governance. -2. **Issuer Operator** — submits signed behavioral evidence. -3. **Verifier / Service Owner** — enforces trust at action boundaries. -4. **Agent Builder** — makes agents token-aware. +1. **Network Core Operator** - runs Trust Authority and governance. +2. **Issuer Operator** - submits signed behavioral evidence. +3. **Verifier / Service Owner** - enforces trust at action boundaries. +4. **Agent Builder** - makes agents token-aware. Suggested starts: - Enterprise platform teams: Core + Verifier diff --git a/docs/integration-guide.md b/docs/integration-guide.md index abf0255..57af6c4 100644 --- a/docs/integration-guide.md +++ b/docs/integration-guide.md @@ -8,7 +8,7 @@ This guide walks through integrating TTP into your services and agent infrastruc - A running Trust Authority (self-hosted or managed). See [reference-implementations/trust-authority](../reference-implementations/trust-authority/). - At least one registered issuer observing your agent. -- The Trust Authority's public key (available at `GET /authority/.well-known/ttp-keys`). +- The Trust Authority's public key (available at `GET /.well-known/ttp-keys`). --- @@ -16,10 +16,15 @@ This guide walks through integrating TTP into your services and agent infrastruc ### Step 1 — Install the SDK +The TypeScript SDK lives in this repository under `sdk/typescript`. The intended package name is `@ttp/sdk`, but it is not yet published to npm. Until publication, treat this section as the stable integration shape and use the local demo for a runnable first pass. + ```bash +# Once published: npm install @ttp/sdk ``` +The examples below use the intended stable import path. + ### Step 2 — Initialize the Client ```typescript @@ -249,30 +254,38 @@ function scoreRequest(req: express.Request, res: express.Response, latencyMs: nu } ``` -See [reference-implementations/issuers](../reference-implementations/issuers/) for a full production-ready issuer. +See [reference-implementations/issuers](../reference-implementations/issuers/) for a fuller issuer example. --- ## Part 4: Trust Authority Setup -### Self-Hosted (Docker) +### Self-Hosted Reference Authority ```bash -# Clone the reference implementation -git clone https://github.com/blocksifr/ttp-protocol +# Clone the repository +git clone https://github.com/blocksifrdev/ttp-protocol cd ttp-protocol/reference-implementations/trust-authority +# Install and build +npm install +npm run build + # Generate keypair npm run generate-keys # Output: authority.public.pem, authority.private.pem (guard the private key) # Configure cp .env.example .env -# Edit .env: set DATABASE_URL, REDIS_URL, KEY_PATH, etc. +# Edit .env for local keys, admin credentials, and network settings. -# Start with Docker -docker-compose up -d +# Start the reference authority +npm start +``` + +In a separate shell, register an issuer and agent: +```bash # Register an issuer curl -X POST http://localhost:3000/v1/admin/issuers \ -H "Authorization: Bearer $ADMIN_KEY" \ diff --git a/docs/public-readiness.md b/docs/public-readiness.md index 455e4ed..13ce3a2 100644 --- a/docs/public-readiness.md +++ b/docs/public-readiness.md @@ -4,14 +4,19 @@ This checklist is used to decide whether TTP is ready for a public launch. ## Current Assessment -**Status:** Almost ready, with a short pre-launch hardening list. +**Status:** Adoption-ready for early technical evaluators; not yet ready for a broad public launch. + +The repo now has a dependency-free local demo that shows the central value proposition: a protected action can be permitted, stepped up, or denied with an execution receipt. The remaining launch gates are mostly packaging, CI, and production-readiness polish. ## Release Gates ### 1) Build & Test Reliability - [x] Trust Authority TypeScript build compiles in local reference environment. -- [ ] Automated CI workflow for build/test/docs checks on every PR. +- [x] Local trust-routing demo runs with `npm run demo`. +- [x] Trust-routing engine tests run with `npm run test:trust-routing`. +- [x] Automated CI workflow for demo/test checks on every PR. +- [ ] Extend CI to build SDK/reference packages and run docs/link checks. - [ ] Basic smoke tests for key admin/token endpoints. ### 2) Documentation Quality @@ -19,7 +24,9 @@ This checklist is used to decide whether TTP is ready for a public launch. - [x] Role-based onboarding docs are split by audience (`getting-started`, `operator-guide`, `ecosystem-integrations`). - [x] Contributing guide is role-based and structured. - [x] Integration guide includes AGT and network adapter patterns. -- [ ] Add a concise "public quickstart" issue template for first-time contributors. +- [x] README leads with a concrete runtime trust gate and local demo. +- [x] Add a concise "public quickstart" issue template for first-time contributors. +- [ ] Publish SDK/package installation path or keep all public docs on local/Git installs. ### 3) Security & Governance Baseline @@ -32,12 +39,13 @@ This checklist is used to decide whether TTP is ready for a public launch. - [x] Agent registry listing endpoint exists (`GET /v1/admin/agents`). - [x] Quarantine/block workflows documented and implemented. +- [x] Dependency-free resolver/routing demo exists for first evaluation. - [ ] Add persistent-storage guidance for production-like deployments in a dedicated operator runbook section. ### 5) Repo Hygiene - [x] Core docs references resolve (roadmap, guides, contributing). -- [ ] Add CI badge/status in README once workflow is live. +- [ ] Add CI badge/status in README once workflow is live and passing. - [x] CODEOWNERS exists for protocol/security/runtime critical paths. ### 6) Open-Source Boundary Integrity @@ -48,10 +56,11 @@ This checklist is used to decide whether TTP is ready for a public launch. ## Recommended Pre-Public Action Plan (Fast) -1. Add CI workflow (build + test + markdown/link checks). -2. Enforce branch protection + required checks in repository settings. -3. Add one smoke-test script for core Trust Authority endpoints. -4. Cut a tagged pre-release (`v1.0.0-rc1`) with changelog. -5. Run open-source boundary audit against `docs/open-source-boundary.md`. +1. Publish or explicitly reserve the SDK package name used in docs. +2. Extend CI to build SDK/reference packages and run markdown/link checks. +3. Enforce branch protection + required checks in repository settings. +4. Add one smoke-test script for core Trust Authority endpoints. +5. Cut a tagged pre-release (`v1.0.0-rc1`) with changelog. +6. Run open-source boundary audit against `docs/open-source-boundary.md`. -If those are done, the repo is in strong shape for public launch. +If those are done, the repo is in strong shape for a broader public launch. diff --git a/examples/basic-agent/index.ts b/examples/basic-agent/index.ts index 2a4e591..d8652f3 100644 --- a/examples/basic-agent/index.ts +++ b/examples/basic-agent/index.ts @@ -5,20 +5,20 @@ * * To run this example: * 1. Start the Trust Authority: cd reference-implementations/trust-authority && npm run dev - * 2. Install dependencies: npm install @ttp/sdk + * 2. Install dependencies from this repo until the SDK is published: npm install ./sdk/typescript * 3. Run: ts-node examples/basic-agent/index.ts */ import { TTPClient, TTPUnavailableError } from "@ttp/sdk" -// ─── Configuration ──────────────────────────────────────────────────────────── +// Configuration const AUTHORITY_URL = process.env.TTP_AUTHORITY_URL ?? "http://localhost:3000" const AGENT_ID = process.env.TTP_AGENT_ID ?? "agent-dev-001" const AGENT_API_KEY = process.env.TTP_API_KEY ?? "dev-agent-key" const SERVICE_URL = process.env.SERVICE_URL ?? "http://localhost:4000" -// ─── Initialize TTP Client ──────────────────────────────────────────────────── +// Initialize TTP Client const ttp = new TTPClient({ agentId: AGENT_ID, @@ -26,7 +26,7 @@ const ttp = new TTPClient({ authorityUrl: AUTHORITY_URL }) -// ─── Agent Logic ────────────────────────────────────────────────────────────── +// Agent Logic async function run() { console.log(`[Agent] Starting — ID: ${AGENT_ID}`) diff --git a/examples/local-trust-gate-demo.mjs b/examples/local-trust-gate-demo.mjs new file mode 100644 index 0000000..03308cb --- /dev/null +++ b/examples/local-trust-gate-demo.mjs @@ -0,0 +1,117 @@ +import { + computeBindingHash, + createExecutionReceipt, + resolveTrustRoute +} from '../packages/trust-routing-engine/src/index.js' + +const timestamp = new Date().toISOString() + +function executionRequest(overrides = {}) { + const base = { + subject: 'agent://retention-worker', + action: 'deploy.production', + resource: 'github:blocksifrdev/ttp-protocol/actions/deploy', + context: { + environment: 'production' + }, + attestationRef: 'att://gateway/recent-behavior', + requestedBy: 'github-actions', + paramsHash: 'sha256:deploy-plan-42', + timestamp, + delegationHopCount: 0, + ...overrides + } + + return { + ...base, + bindingHash: computeBindingHash({ + subject: base.subject, + action: base.action, + resource: base.resource, + paramsHash: base.paramsHash, + timestampBucket: base.timestamp.slice(0, 16) + }) + } +} + +function routeCandidate(overrides = {}) { + return { + issuerType: 'behavioral', + issuerId: 'issuer://ci-runtime', + proofRef: 'proof://ci-runtime/last-5m', + trustScore: 0.94, + lastVerifiedAt: new Date(Date.now() - 30_000).toISOString(), + freshnessSeconds: 120, + revoked: false, + delegationAllowed: true, + maxHops: 2, + currentHopCount: 0, + grantId: 'grant://production-deploy', + minTrustScore: 0.72, + requiresStepUp: false, + action: 'deploy.production', + environmentConstraints: { + environment: 'production' + }, + ...overrides + } +} + +const scenarios = [ + { + name: 'PERMIT trusted build action', + request: executionRequest({ + action: 'build.run', + resource: 'github:blocksifrdev/ttp-protocol/actions/build' + }), + candidates: [ + routeCandidate({ + action: 'build.run', + grantId: 'grant://ci-build', + requiresStepUp: false + }) + ] + }, + { + name: 'STEP_UP production deploy', + request: executionRequest(), + candidates: [ + routeCandidate({ + requiresStepUp: true + }) + ] + }, + { + name: 'DENY revoked workload', + request: executionRequest({ + subject: 'agent://compromised-worker' + }), + candidates: [ + routeCandidate({ + revoked: true + }) + ] + } +] + +let priorReceiptHash = '' + +for (const scenario of scenarios) { + const decision = resolveTrustRoute({ + request: scenario.request, + candidates: scenario.candidates + }) + const receipt = createExecutionReceipt({ + request: scenario.request, + decision, + priorReceiptHash + }) + priorReceiptHash = receipt.chainHash + + console.log(`\n${scenario.name}`) + console.log(`decision: ${decision.decision}`) + console.log(`reason: ${decision.reasonCodes.join(', ')}`) + console.log(`trust: ${decision.trustScoreAtDecision.toFixed(3)} (${decision.trustZone})`) + console.log(`receipt: ${receipt.receiptId}`) + console.log(`chain: ${receipt.chainHash.slice(0, 16)}...`) +} diff --git a/package.json b/package.json index e7a5013..dc8fb59 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "private": true, "type": "module", "scripts": { + "demo": "node examples/local-trust-gate-demo.mjs", "test:trust-routing": "node --test packages/trust-routing-engine/tests/*.test.mjs" } }