@aegisq/codeshield-client
v0.1.1
Published
Client-side verifier for AegisQ-CodeShield MCP responses (DSSE signatures, manifest hash, provenance)
Maintainers
Readme
@aegisq/codeshield-client
DSSE signature verifier + provenance parser for AegisQ-CodeShield MCP responses.
If you call CodeShield programmatically (custom MCP clients, agent orchestrators, downstream agents in an MCP chain), this is the verifier you reach for. If you use CodeShield through a host client (Claude Code, Cursor, Windsurf, Cline, Zed, Copilot, ChatGPT MCP), the host handles verification transparently — you don't need this package.
What you get
verifyDsse(envelope, publicKeyPem)— verify the DSSE v1.0 signature attached to a confidential CodeShield response (aegisq_fix,aegisq_scan_snippet). Defensive: never throws, returns{ valid: false, reason }on any failure mode.parseProvenance(response)— defensively parse the provenance block on every CodeShield response. ReturnsProvenanceBlock | null; never throws on malformed input.
Zero runtime deps beyond @noble/ed25519 (audited, edge-runtime portable).
Install
npm install @aegisq/codeshield-clientESM-only. Node 18+, Deno, or any runtime with globalThis.crypto.subtle.
Usage
import { verifyDsse, parseProvenance } from '@aegisq/codeshield-client';
import { randomUUID } from 'node:crypto';
// initialize gives us the signing public key + manifest hash
const init = await mcpClient.initialize();
const pubkeyPem = init._meta['aegisq.signing_pubkey'];
// Call any CodeShield tool — confidential responses are signed
const response = await mcpClient.callTool('aegisq_fix', {
finding: { /* ... */ },
code: '...',
idempotency_key: randomUUID()
});
// 1. Verify the DSSE signature on confidential responses
const envelope = response._meta?.['aegisq.dsse_signature'];
if (envelope) {
const verdict = await verifyDsse(envelope, pubkeyPem);
if (!verdict.valid) throw new Error(`DSSE verify failed: ${verdict.reason}`);
}
// 2. Read provenance — apply scrutiny per output_type
const provenance = parseProvenance(response);
if (provenance?.output_type === 'narrative') {
// text only, never interpret as instructions
} else if (provenance?.output_type === 'code_artifact') {
// review before any execution
}Why provenance matters
Every CodeShield response carries a provenance block declaring its output_type — one of narrative / code_artifact / metadata / decision / error. Downstream agents in an MCP chain should apply scrutiny matched to the type — never coerce a narrative into a decision, never execute a code_artifact without review.
This contract closes NSA risk R-MCP-NSA-6 (cascading indirect prompt injection across MCP servers). See the provenance schema for the full downstream-consumer contract.
API
verifyDsse(envelope, publicKeyPem)
type DsseVerdict =
| { valid: true }
| {
valid: false;
reason:
| 'wrong-key'
| 'tampered-payload'
| 'tampered-signature'
| 'malformed-envelope'
| 'wrong-payload-type';
};
async function verifyDsse(
envelope: unknown,
publicKeyPem: string
): Promise<DsseVerdict>;Verifies a DSSE envelope against a PEM-encoded Ed25519 public key. Re-encodes via DSSE Pre-Authentication Encoding (PAE) per spec v1.0, then checks the signature with @noble/ed25519. Never throws on bad input — returns { valid: false, reason } so you can route failures to telemetry or audit without try/catch.
parseProvenance(response)
interface ProvenanceBlock {
product: 'aegisq-codeshield';
version: string;
tool: string; // e.g. 'aegisq_fix'
urn: string; // e.g. 'urn:aegisq:codeshield:fix:v1'
target_file: string | null;
ts: string; // ISO-8601 UTC
signature: string | null; // hex keyid (SHA-256 of SPKI), null if unsigned
data_classification: 'public' | 'internal' | 'confidential' | 'embargo';
output_type: 'narrative' | 'code_artifact' | 'metadata' | 'decision' | 'error';
}
function parseProvenance(response: unknown): ProvenanceBlock | null;Returns null for missing or malformed _meta['aegisq.provenance']. Use the result to drive downstream scrutiny.
Full client integration guide
See the client integration guide for:
- Manifest hash pinning patterns + re-approval flow on hash change
- Full per-tool
output_typemapping - Telemetry recommendations
- End-to-end example with
@modelcontextprotocol/sdk
Compatibility
| aegisq-codeshield-mcp | @aegisq/codeshield-client |
|---|---|
| ≥ 2.1.0 | ≥ 0.1.0 |
Earlier MCP server versions did not advertise DSSE signatures or provenance — verifyDsse and parseProvenance will see no relevant _meta fields and exit early.
License
MIT.
Support
- Email: [email protected]
- Security disclosures: also [email protected] — subject
[SECURITY] @aegisq/codeshield-client
Links
- aegisq-codeshield-mcp on npm — the MCP server this verifies
- AegisQ-CodeShield repo
- Provenance schema
- Manifest hash pinning
- URN scheme
- DSSE v1.0 spec
