Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 54 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
| Prepare, commit, verify, and compensate lifecycle | Side effects become explicit, approval-aware, and checkable instead of hidden inside an agent loop. |
| Configurable conformance profiles | The same application can apply stricter evidence rules to enterprise, regulated, local, or distributed runs. |
| Plain-language explanation and Execution Passport | Technical run evidence can be shared with non-specialists and bound to external attestations without embedding the full payload. |
| Optional authenticated Passport verification | A relying party can require an exact trusted signer and reject a removed, altered, or substituted DSSE envelope without coupling the core to one trust provider. |

> **Maturity and limits:** this is an executable alpha reference architecture,
> not a hosted agent platform or regulatory certification. Digital fingerprints
Expand Down Expand Up @@ -76,6 +77,7 @@ Logical strata may share one process. The rule is a dependency and responsibilit
- An RFC 8785 JSON Canonicalization Scheme implementation with cross-language golden vectors, strict duplicate-member rejection at the JSON boundary, and a hash-linked receipt chain with tamper and missing-evidence detection.
- Runtime conformance checks for rooted authority, causal evidence, actual budget consumption, exact-action idempotency, approval, read-back or compensation, predeclared criterion evidence bindings, layer direction, and model/authority separation.
- An [Execution Passport v2](docs/spec/attestations/execution-passport/v2/README.md) that binds one run bundle, its complete conformance report, one externally validated OASF record, and optional run-bound observations in a strict in-toto Statement without embedding those documents.
- Provider-neutral authenticated consumer composition plus an optional `agentic-strata/sigstore` adapter that verifies DSSE structure, exact canonical Passport bytes, cryptographic trust, and an exact issuer-plus-SAN allowlist.
- Mapping-only adapter documents for AG-UI, A2A, MCP, OpenTelemetry GenAI, CloudEvents, an external policy engine, and OASF, plus an executable StageFabric evidence-reduction adapter.
- A neutral prepare/commit/read-back demo with exact-action approval and duplicate suppression.

Expand Down Expand Up @@ -139,6 +141,56 @@ semantics. Repeat `--execution-evidence` and

`bind-stagefabric` accepts only the exact canonical JSON plus trailing LF emitted by the StageFabric evidence writer. Pretty-printed JSON, YAML, or a reserialized object is rejected because the resulting descriptor digest identifies the retrievable file bytes, not merely an equivalent object.

### Optional authenticated verification

The root package has no runtime dependency on Sigstore. Install the optional
peers only in a relying party that needs Sigstore verification:

```bash
npm install agentic-strata sigstore@5 @sigstore/bundle@5
```

```js
import { verifyAuthenticatedExecutionPassport } from "agentic-strata";
import {
createPublicSigstoreEnvelopeVerifier
} from "agentic-strata/sigstore";

const verifier = await createPublicSigstoreEnvelopeVerifier({
identityPolicy: {
allowedSigners: [{
issuer: "https://token.actions.githubusercontent.com",
subjectAlternativeName: "https://github.com/example/project/.github/workflows/release.yml@refs/heads/main"
}]
},
thresholds: { ctLog: 1, tlog: 1 }
});

const result = await verifyAuthenticatedExecutionPassport({
passport,
bundle,
report,
oasfRecord,
executionEvidenceResources,
envelope: sigstoreBundle,
verifier
});
```

The identity values are literal exact matches, never regular expressions or
wildcards. An enterprise or offline deployment can instead pass its own trusted
Sigstore `BundleVerifier` to `createSigstoreEnvelopeVerifier`. That injected
verifier owns its certificate, log, timestamp, revocation, and private-root
policy; AgenticStrata does not claim to introspect its configuration. A bare
Statement, non-DSSE bundle, second
signature, different payload type, non-canonical payload bytes, failed trust
verification, or different signer fails closed. The adapter verifies only; it
does not obtain OIDC tokens or sign Passports.

Sigstore 5 currently requires Node.js `^22.22.2 || ^24.15.0 || >=26.0.0`.
This narrower requirement applies only when importing `agentic-strata/sigstore`;
the root package remains usable on Node.js 22 or newer.

All commands accept JSON; `validate` and `lint` also accept YAML. Build once with `npm run build` before invoking the repository-local CLI. Input documents are bounded to 16 MiB, JSON member names must be unique, and YAML alias expansion is limited.

## Profiles
Expand Down Expand Up @@ -179,6 +231,7 @@ Read [Architecture](docs/architecture.md), [Contracts and conformance](docs/cont
- Run status and conformance status are separate: a failed run can still have an intact, conformant evidence record, but it is never explained as a completed outcome.
- Reports bind the evaluator name, package version, semantic revision, selected rule set, and effective profile configuration. The evaluator digest identifies the declared implementation revision; it is not a code signature.
- An unsigned Execution Passport proves deterministic integrity and cross-artifact binding only. Authenticity requires an externally verified DSSE envelope or equivalent trusted channel, and consumers must make that requirement explicit so removing a signature cannot silently downgrade policy.
- `verifyAuthenticatedExecutionPassport` composes complete artifact-set verification with one injected envelope verifier. The optional Sigstore subpath enforces DSSE-only input, one signature, exact canonical payload bytes, and literal issuer-plus-SAN authorization. Its public-TUF factory also wires positive CT/Rekor thresholds; an injected enterprise verifier owns and must enforce its own trust thresholds, root lifecycle, and revocation policy.
- Consumer verification requires the complete supplied subject set and exact bytes for every execution-evidence resource; validating the Passport schema alone does not verify those bindings.
- The OASF subject digest proves which opaque record was bound; it does not prove that the record is semantically valid OASF. Validate it before passport creation with the specification owner’s tooling.
- Execution-placement evidence enters the predicate only as a strict, run-bound, observation-only descriptor with a normalized observation time and no payload or `content` field. A StageFabric descriptor hashes the exact canonical JSON file bytes, including its trailing LF. Descriptor metadata must come from a trusted producer and be redacted or pseudonymized when sensitive; its optional stable URI may be omitted. Full provider result objects are outside the Passport contract.
Expand All @@ -193,6 +246,6 @@ Read [Architecture](docs/architecture.md), [Contracts and conformance](docs/cont
npm run release:check
```

The release gate runs strict lint and types, 80+ tests with coverage thresholds, build, repository hygiene, production audit, `publint`, and Are the Types Wrong.
The release gate runs strict lint and types, 100+ tests with coverage thresholds, build, repository hygiene, production audit, `publint`, and Are the Types Wrong.

Apache-2.0 licensed. See [CONTRIBUTING.md](CONTRIBUTING.md) and [SECURITY.md](SECURITY.md).
55 changes: 55 additions & 0 deletions docs/adr/0006-authenticated-passport-verification.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# ADR 0006: Provider-neutral authenticated Passport verification

Status: accepted for v0.4

## Context

Execution Passport v2 and `verifyExecutionPassport` establish deterministic
binding across the supplied Statement, run bundle, conformance report, OASF
record, and external execution-evidence bytes. They intentionally do not prove
who produced a wholly self-consistent artifact set. Consumers that require
authenticity need a fail-closed composition without coupling the contract core
to Sigstore, a public trust root, or one identity provider.

## Decision

The root export provides `verifyAuthenticatedExecutionPassport` and a generic
`EnvelopeVerifier` port. Artifact-set verification always runs first. The port
receives the exact RFC 8785 UTF-8 Passport bytes and fixed payload type
`application/vnd.in-toto+json`; a final authenticated result requires a complete
verified signer and a matching authenticated-payload digest. Exceptions,
missing evidence, failed verification, and a bare Statement remain unverified.
There is no automatic unsigned fallback.

Sigstore support is isolated behind the optional `agentic-strata/sigstore`
subpath. `sigstore` and `@sigstore/bundle` are optional peer dependencies and
the root index never imports the adapter. The adapter supports either an
injected, caller-trusted `BundleVerifier` for enterprise or offline trust
material, or a factory using the public Sigstore client and TUF options. Only
the public factory owns and wires configured CT/Rekor thresholds; an injected
verifier's trust enforcement is explicitly caller-owned.

The Sigstore boundary requires:

- DSSE rather than a message signature;
- exactly one signature;
- exact payload type and byte equality with the canonical Passport;
- CT-log and Rekor thresholds of at least one when using the public factory;
- a cryptographically verified signer containing both issuer and SAN; and
- literal equality with one configured issuer-plus-SAN pair.

Identity policy has no regular-expression, wildcard, or issuer-only mode.

## Consequences

- Core consumers can integrate other authenticated-envelope systems without a
Sigstore dependency.
- Installing and importing the root package does not install or load Sigstore.
- Removing or replacing a DSSE envelope cannot silently downgrade an
authenticated-required decision.
- Private trust material and public TUF trust can use the same adapter surface.
- The adapter performs verification only. Signing, OIDC token acquisition, key
custody, root distribution and refresh, revocation, and trusted timestamping
remain deployment responsibilities.
- Sigstore 5 currently supports one signature in a bundle; multi-party or
threshold-signature policy requires a future, separately versioned design.
12 changes: 11 additions & 1 deletion docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,17 @@ expected Statement, checks the complete bundle/report relationship again, and
requires a one-to-one digest match for external evidence. Schema validation by
itself is deliberately insufficient.

The core emits an unsigned Statement. A replaceable external adapter may wrap its exact RFC 8785 bytes in DSSE and use Sigstore or another trust system. Signature verification, signer identity, transparency-log policy, and trusted time remain consumer-owned controls.
The core emits an unsigned Statement. `verifyAuthenticatedExecutionPassport`
first verifies the complete artifact set, then delegates the envelope to an
injected provider-neutral verifier over the exact RFC 8785 Statement bytes. It
never falls back to unsigned acceptance. The optional `agentic-strata/sigstore`
subpath admits only one-signature DSSE bundles with payload type
`application/vnd.in-toto+json`, exact payload bytes, and an exact issuer-plus-SAN
allowlist. The public Sigstore TUF factory additionally wires positive CT/Rekor
thresholds. Enterprise and offline trust stores inject their own compatible,
trusted verifier and own its certificate, log, timestamp, and revocation policy.
Signing, key custody, trust-root lifecycle, and stronger trusted-time policy
remain outside the core.

## Safe semantic caching

Expand Down
25 changes: 25 additions & 0 deletions docs/contracts-and-conformance.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,31 @@ unreferenced files fail verification. The CLI exposes the same operation as
`verify-passport`. This verifies an unsigned artifact set, not producer identity,
OASF semantics, trusted time, or an external DSSE envelope.

Authenticated verification is a separate composition, not a new Passport
schema. `verifyAuthenticatedExecutionPassport` first runs the complete unsigned
artifact-set verification. Only after that succeeds does it pass the exact UTF-8
RFC 8785 Statement bytes and fixed in-toto payload type to an injected envelope
verifier. The final result is authenticated only when the external verifier
returns a complete signer and the digest of those same bytes. A failed or
removed envelope cannot be reinterpreted as unsigned success.

The optional `agentic-strata/sigstore` export supplies two constructors:

- `createSigstoreEnvelopeVerifier` wraps a caller-trusted Sigstore
`BundleVerifier` for private, offline, or test environments; the caller owns
its certificate, log, timestamp, revocation, and trust-root policy;
- `createPublicSigstoreEnvelopeVerifier` obtains the public Sigstore verifier
using explicit TUF options and thresholds.

Both require DSSE rather than a message signature, exactly one signature,
payload type `application/vnd.in-toto+json`, byte equality with the canonical
Passport, and one literal issuer-plus-SAN allowlist match. The public factory
also rejects CT or Rekor thresholds below one and passes accepted values to
Sigstore. The injected factory cannot introspect its trusted `BundleVerifier`
and therefore makes no threshold claim on its behalf. Identity inputs are not
regular expressions. Root loading, cache freshness, revocation decisions, and
any policy stronger than the underlying verifier remain consumer responsibilities.

## Evidence, not file detection

A conformance run consumes a `RunBundle`. It does not infer architecture from directory names, imports, or keywords. This avoids declaring success simply because a project contains a policy file or telemetry package. Conversely, a source scanner remains useful before runtime evidence exists; its result should be treated as a discovery signal rather than runtime proof.
Expand Down
8 changes: 7 additions & 1 deletion docs/interoperability.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Adapter YAML files are declarative mappings with an explicit `lossPolicy`. They

## Attestation exchange

The Execution Passport uses the project-controlled predicate namespace documented at [`docs/spec/attestations/execution-passport/v2`](spec/attestations/execution-passport/v2/README.md). The core writes exact RFC 8785 Statement bytes. A deployment may pass those bytes to an external DSSE/Sigstore adapter using payload type `application/vnd.in-toto+json`; no signing key, certificate flow, or Sigstore dependency enters AgenticStrata.
The Execution Passport uses the project-controlled predicate namespace documented at [`docs/spec/attestations/execution-passport/v2`](spec/attestations/execution-passport/v2/README.md). The core writes exact RFC 8785 Statement bytes and has no Sigstore import. A deployment may verify a DSSE envelope through the provider-neutral authenticated-verifier interface. `agentic-strata/sigstore` is a separately exported optional subpath whose Sigstore packages are optional peers; importing the root package does not load or install them. No signing key, OIDC flow, or certificate issuance enters AgenticStrata.

Consumers choose one of two explicit policies:

Expand All @@ -28,6 +28,12 @@ Consumers choose one of two explicit policies:

There is no implicit fallback from the second policy to the first. This prevents signature removal from becoming a silent trust downgrade.

The Sigstore adapter supports either an injected `BundleVerifier` with
enterprise or offline trust material, or the public client factory with TUF
options. It deliberately accepts only exact issuer and subject-alternative-name
pairs. Regular-expression identity policy, signing, key management, and
multi-signature semantics are outside this adapter.

## Agent and flow specifications

Portable agent specifications answer questions such as “what is this agent, which tools may it request, and how is a flow assembled?” AgenticStrata answers “what did this application run actually request, authorize, change, verify, and prove?”
Expand Down
9 changes: 5 additions & 4 deletions docs/spec/attestations/execution-passport/v2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,16 @@ the exact bytes of every execution-evidence resource. The verifier:

This is unsigned artifact-set verification. Producer-contract semantics are
validated by the adapter that creates a binding; OASF semantics remain with its
owner. Authenticity, signer identity, trusted time, revocation, and protection
against wholesale replacement still require an externally verified envelope or
trusted store.
owner. `verifyAuthenticatedExecutionPassport` can compose this complete check
with an injected external envelope verifier without changing the Statement
schema. Authenticated-required mode never falls back to unsigned acceptance.
Trusted time, revocation, and trust-root lifecycle remain consumer policy.

## OASF, DSSE, and signing boundaries

OASF input is an opaque I-JSON object. Validate it with the owning ecosystem before Passport creation; its subject digest proves which canonical bytes were bound, not semantic OASF validity.

For authenticity, wrap the exact RFC 8785 Statement bytes in a DSSE envelope with payload type `application/vnd.in-toto+json`, then enforce signer identity, trust material, freshness, revocation, and transparency policy outside AgenticStrata. Consumers explicitly choose either unsigned integrity or authenticated-required policy; there is no automatic downgrade.
For authenticity, wrap the exact RFC 8785 Statement bytes in a DSSE envelope with payload type `application/vnd.in-toto+json`, then enforce signer identity, trust material, freshness, revocation, and transparency policy. The optional `agentic-strata/sigstore` verifier requires one DSSE signature, byte equality with the canonical Statement, and a literal issuer-plus-SAN allowlist. Its public-TUF factory also wires positive CT/Rekor thresholds; a caller-injected verifier owns its own threshold and trust policy. Sigstore dependencies are optional peers and are not imported by the root package. Consumers explicitly choose either unsigned integrity or authenticated-required policy; there is no automatic downgrade.

## Versioning and v1 migration

Expand Down
Loading
Loading