The unavoidability arc, 3 moves, in dependency order
The provability layer is done: every approved action carries a signed, content-bound, single-use authorization that receiving systems verify independently, byte-for-byte. What that does not yet do is make Parmana’s authorization unavoidable, not just verifiable. The gap is narrower than it used to be, though: the default server wires the gateway unconditionally and routes every connector it registers through credential isolation, so for a registered connector, the calling AI does not hold the execution credential, the gateway does, briefly, and only inside its own boundary. Move 2 below covers what’s still missing for the broader claim.Move 1: KMS / HSM key custody, [ROADMAP], roughly 1-2 weeks once started
Today:FileKeyProvider reads a PEM file from disk (KEY_PROVIDER=local, the only
implemented provider). KeyProviders declares aws-kms/azure-key-vault/gcp-kms/hsm
as config values with zero implementing classes behind any of them. This is the exact
exposure class that produced the committed-key incident on Security.
Setting KEY_PROVIDER to one of these four fails startup loudly (KeyBootstrap.create()
throws, naming the configured value) rather than silently falling back to FileKeyProvider;
the underlying absence of a real KMS/HSM provider remains.
Unlocks: “Parmana’s signing key cannot be exfiltrated from the application process.”
What’s pending, precisely: a real KeyProvider implementation (getPrivateKey,
getPublicKey, hasKey, getMetadata; see packages/crypto/src/KeyProvider.ts) for at
least one of aws-kms/azure-key-vault/gcp-kms/hsm, registered in KeyBootstrap.ts
in place of today’s fail-closed throw for that value.
Why it’s still pending, not just unscheduled: this repo’s own evidence bar for a
Supported claim is a live test against a real key in a real account. “A fake/mock
passing proves nothing here” is not a rhetorical flourish, it’s the same standard the
durable rate limiter was held to before being marked working. A KeyProvider implementation
can be written and unit-tested
against a stubbed cloud SDK client entirely offline, which proves the code is
structurally correct, not that it actually works against the real service (correct IAM
permission scoping, correct key ARN/resource-id format, the signature actually verifying
against the returned public key, etc.). None of that can be verified without a real
AWS/Azure/GCP account and credentials, which this development environment does not have
and a code-writing session cannot manufacture for itself.
What building it actually needs, in order:
- Resolve the algorithm question below first. It changes what the provider signs, not just how it fetches the key.
- Pick one provider to start with (AWS KMS is the most likely first target: broadest existing tooling, most common in this codebase’s target deployments).
- A real account + credentials with a KMS key already provisioned, scoped to exactly the sign/verify operations this provider class needs, not broader IAM permissions than required.
- Implement the
KeyProviderinterface against that SDK, followingFileKeyProvider.ts’s existing shape (including itsassertValidKeyIdpath-safety discipline, translated to whatever the cloud SDK’s own key-identifier validation needs to be). - Wire it into
KeyBootstrap.create(), replacing the current throw for that oneKEY_PROVIDERvalue only. The other three stay fail-closed until each gets the same treatment. - Run a live sign/verify round trip against the real key before claiming this as
Supported anywhere in
docs/CLAIMS.md. A passing unit test against a mock does not satisfy this repo’s own bar, stated above.
ecdsa-p256 (already declared in SignatureAlgorithms, unused today) for KMS-backed keys
specifically? ML-DSA-65 (this codebase’s post-quantum signer) is not yet broadly available
in any major cloud KMS. A KMS-backed deployment may need to run classical-only, or hybrid
mode with the PQ half still file-based, an inconsistency worth deciding on deliberately
rather than discovering mid-implementation.
Move 2: Credential brokering, [PARTIAL], wired for the registered connector, full claim is [ROADMAP]
Today, precisely:packages/execution-control is real and tested (11 tests) and wired
into the default server: ExecutionControlService authenticates a calling gateway, issues a
short-lived InMemoryGatewaySessionStore session, and only then invokes a connector,
auditing every step. InMemorySessionCredentialVault isolates the credential from the caller
within that flow. This is real, tested, and running in the default server for each
registered connector, see Credential isolation for the
precise scope note. It is still an in-process, in-memory scaffold, not a cross-system
claim about arbitrary connectors.
What’s still missing for the actual claim: real cloud-provider credential minting (the
plan targets AWS STS: a verified envelope causes the gateway to mint a short-lived,
action-scoped credential, use it, and discard it, the AI never receives it, structurally),
and a general-purpose path to register a new connector into this seam without a bootstrap
code change. InMemorySessionCredentialVault and InMemoryGatewaySessionStore are
dev/reference-grade names for a reason, no STS integration, no persistence, no cross-process
session sharing exists yet. The strategy doc is explicit that this move “needs a design
partner, not a mock”, a fake AWS account proves nothing a diligence review would trust.
Unlocks (scoped): “For [action class] on AWS, AI never possesses execution
credentials.” Scoped to the integrated system class, never claimed universally.
Schema note: extending the envelope with resource/action fields for this is a
signed-artifact format change, requiring a dedicated versioned session (the version field
already in ExecutionAuthorizationPayload exists for exactly this reason).
Move 3, Network enforcement + bypass detection, [ROADMAP], needs a partner’s red team
What: network-policy templates (firewall / security-group / K8sNetworkPolicy) so a
target’s ingress accepts traffic only from the gateway, plus a reconciliation loop
comparing the target’s own activity log against issued authorizations, anything without a
matching envelope raises an alert.
Why last: it’s a property of a customer’s deployment, proven by a partner’s security
team trying to break it, not by a unit test.
Unlocks (permanently scoped): “Non-bypassable per integrated system under the
reference deployment; bypass detected everywhere.” The unscoped “non-bypassable, period”
claim is never made, see Security.