import { type ToolRegistryEntry } from '../../core/tool-integrity.js'; import { type CapabilityPin, type ReferentBindingResult, type ToolAttestationObservation } from './types.js'; /** Run the SDK's existing `verifyToolIntegrity` and record what it found, in the shape * `evaluateCapabilityBinding` consumes. * * `resolveTrustedAttestorKey` is keyed BY TOOL NAME, never by the `attestorId` the * presented entry asserts about itself. That is the whole reason this is a callback: a * valid signature establishes who signed, and standing to attest a particular tool is * resolved outside the record asserting it. An entry signed by a perfectly real attestor * who is not the attestor for this tool comes back with * `attestor_signature_valid: false`. * * Returns `attestor_key_resolved: false` and `attestor_signature_valid: false` when no key * resolves, and does not run the signature check in that case. PROPOSED. */ export declare function observeToolAttestation(input: { registryEntry: ToolRegistryEntry; requestedToolName: string; /** The implementation bytes actually reachable behind the tool name now. */ observedImplementation: string | Buffer; resolveTrustedAttestorKey: (toolName: string) => string | null | undefined; }): ToolAttestationObservation; export interface CapabilityBindingInput { /** The tool the action is about to go through. */ readonly requestedToolName: string; /** Every scope grant the presented delegation carries, used for the required-scope check. * Pass the leaf grant's own array: narrowing across a chain is chain verification's job * and has already happened by the time this runs. */ readonly grantedScopes: readonly string[]; /** Scopes the action declares it needs, `scope_required` from an `aps-action-ref-v2` * action reference. Default empty. */ readonly requiredScopes?: readonly string[]; /** The pin the grant carries for this tool. `null` means THE GRANT DOES NOT NAME THE TOOL * AT ALL, which is a different answer from a grant that names it and pins nothing (a pin * with both digest arrays empty). The caller passes it explicitly; there is no default, * because a default here would be the design decision. Build it with * `parseCapabilityPinFromScopeGrants`. */ readonly pin: CapabilityPin | null; /** What the caller established about the tool's attestation, from * `observeToolAttestation`. `null` means none was presented. */ readonly attestation: ToolAttestationObservation | null; /** `sha256:` digest of the implementation reachable behind the tool name now. `null` means * the caller observed nothing, which this module reports rather than assuming a match. * Compute with `capabilityImplementationDigest`. */ readonly observedImplementationDigest: string | null; /** `sha256:` digest of the metadata the tool declares now. `null` means the caller * observed nothing. Compute with `capabilityMetadataDigest`. */ readonly observedMetadataDigest: string | null; } /** Decide whether an action through `requestedToolName` is established under the grant that * carries `pin`. * * Five ordered steps, each one the reason a vector in the `capability-binding-drift` * candidate family exists: * * 1. Does the grant name the tool, and does it carry the scopes the action declares. * 2. Is there an accepted attestation for this tool, from an attestor resolved for the * tool, and does that signed claim still describe the implementation observed NOW. A * registry entry is a claim; this step is what says the claim is not stale. * 3. The implementation pin. Compared against the ATTESTED digest, which step 2 has * already established equals the observed digest, so the comparison is against a digest * an attestor vouched for rather than against an unattested observation. * 4. The declared-metadata pin, pinned and checked separately from the implementation. * 5. Nothing left outstanding. * * Never returns an artifact verdict and never makes any delegation invalid. PROPOSED. */ export declare function evaluateCapabilityBinding(input: CapabilityBindingInput): ReferentBindingResult; //# sourceMappingURL=binding.d.ts.map