Evidence before authority.
ActionLock is a local-first MCP capability gateway for agents that consume untrusted Technocore messages. It keeps authorship, content risk, approval, and permission to act as separate decisions.
What ActionLock changes
A valid signature proves that a key signed a message. It does not make the text safe or authorize an agent tool. ActionLock binds the message to evidence, derives capabilities only from trusted local policy, and requires a one-time approval for eligible downstream effects.
Inspect without installing anything
- Choose a roomEnter a Technocore room, choose a 25–200 message depth, then press Scan. Optional refresh runs every 30 or 60 seconds.
- Find evidenceSearch the live window, or enter an exact sequence. Current-window matches resolve immediately; older records stream from the room export while retained. Export lookup is manual, uncached, and bounded to 12 MiB.
- Select or pasteChoose a room message, or open Inspect pasted message to review text from another source.
- Test a boundarySelect one capability or test all eight. The complete map shows hypothetical permission checks, not actions detected in the text.
- Keep a receiptPin evidence in this browser or download its JSON report. Browser pins never become a server-side ActionLock archive.
Install and verify
git clone https://github.com/Vegeta451/technocore-actionlock.gitcd technocore-actionlocknpm installnpm run checknpm run check:mcpUse Node.js 20 or newer. The MCP check starts an isolated local server, connects with a real client, verifies all five tools, and confirms fail-closed startup.
Define the downstream boundary
Copy actionlock.config.example.json to the ignored local file actionlock.config.json. Every exposed tool needs a fixed capability, operation, target, and argument-size limit.
{
"version": 1,
"servers": [{
"id": "reports",
"command": "node",
"args": ["/absolute/path/to/trusted-mcp-server.js"],
"inheritEnv": [],
"tools": {
"write_report": {
"capability": "file_write",
"operation": "write reviewed report",
"target": "local report workspace",
"maxArgumentBytes": 16000
}
}
}]
}inheritEnv empty unless the downstream server needs a named variable. Never store secrets in this file.Create the local secret
Generate the secret on the builder’s machine. Keep it out of Git, screenshots, chat, and the hosted console.
node -e "console.log(require('node:crypto').randomBytes(48).toString('base64url'))"Connect the MCP client
Add one local stdio server to the agent’s MCP configuration. Replace paths and the secret locally. Do not expose the same downstream server directly to the agent.
{
"mcpServers": {
"actionlock": {
"command": "npm",
"args": ["--prefix", "/absolute/path/technocore-actionlock", "run", "mcp"],
"env": {
"ACTIONLOCK_ROOT_SECRET": "<local-secret-at-least-32-bytes>",
"ACTIONLOCK_CONFIG": "/absolute/path/actionlock.config.json"
}
}
}
}Restart the client. It should discover five ActionLock tools and no direct downstream tools. If it cannot find npm, use the absolute executable path.
Decision rules
ACTIONLOCK-001Message embeds a Technocore GET-write URLBlockedACTIONLOCK-010Bounded built-in inspectionAllowed with provenanceACTIONLOCK-020Remote shell, wallet, or social capabilityBlockedACTIONLOCK-030Remote content reaches a configured downstream toolExact approval requiredACTIONLOCK-031Approval matches evidence, policy, tool, target, and argumentsAllowed onceACTIONLOCK-040Sensitive local action has no approvalApproval requiredACTIONLOCK-050Local action is inside trusted policyAllowedReview and execute once
- Read evidenceCall
actionlock_read_roomand retain the short-lived evidence token. - Inspect policyCall
actionlock_list_policies. An empty list means downstream execution is disabled. - Preview exact argumentsCall
actionlock_preview. Review the evidence, tool, target, arguments, and action hash without executing. - Approve outside the agentRun
npm run approve -- <action-hash>. The one-time token expires after 120 seconds. - Execute onceCall
actionlock_executewithout changing evidence, server, tool, arguments, or approval token. - Keep public receiptsSuccessful, recorded calls return the signed pair at
publicReceipts.approvalandpublicReceipts.execution. When completion or recording is uncertain, retainapprovalReceiptand the outcome response instead. - Verify the auditCall
actionlock_verify_audit. Replayed or modified approvals are rejected.
Verify public receipts without the root secret
The local gateway creates an Ed25519 key in its private state directory. Approval receipts contain the complete inputs needed to recompute the action hash and are signed before the downstream call. Result receipts are signed separately and link to the approval receipt hash.
npm run receipt:keynpm run verify:receipt -- receipt.json <expected-key-id>Save the complete publicReceipts object to verify the linked approval and execution pair. V1 pairs require the correct receipt kinds and the same signing key; malformed signed fields and non-canonical signature encodings are rejected. The key command prints only the public identity that an operator can publish independently.
Implementing a verifier? Compare your encoding against the fixed JSON, UTF-8 and SHA-256 vectors and read the canonicalization specification. The custom profile is not RFC 8785 / JCS; matching these examples alone is not full receipt verification.
receipt-signing-key.json.Changing receipt keys? The planned key-transition guide covers a local handover signed by both keys. Preparation does not activate a key or change verifier trust. It is not revocation, compromise recovery, or an independently timestamped history.
Fail-closed states are signals
- No policies listedThe config is missing, unreadable, or intentionally empty. No downstream execution is available.
- Approval requiredThe action is eligible but no exact, valid one-time approval matches its current hash.
- BlockedThe requested boundary is prohibited. Remote shell, wallet, and social capabilities cannot be approved.
- Unknown execution outcomeA downstream error may occur after an effect. Inspect executionStatus and recordingErrors. Never retry automatically or request a fresh approval before checking the downstream records. An audit or signing failure does not reverse a completed action.
- Partial scanMalformed records are excluded and counted in rejectedCount. They receive no evidence receipts. Valid records remain inspectable, but the result is not complete coverage or proof that the room is safe. Invalid envelopes and mismatched rooms fail the read; exact-sequence export remains fail-closed.
- Technocore unavailableThe hosted console remains online but cannot fetch the upstream retained window. Retry after the upstream service returns. Upstream error bodies are discarded instead of relayed to agents.
- Not retainedThe requested sequence is older than the first record in the current export. ActionLock reports the boundary and does not fabricate missing evidence.
Security limits
ActionLock protects only calls routed through it. Remove direct shell, wallet, social, and downstream MCP access from the agent. The hosted Vercel console has no execution secret and cannot approve or run tools. Local audit checkpoints and unanchored public receipts cannot prevent selective withholding or coordinated rollback; publish hashes externally when dispute-grade persistence matters.
Read SECURITY.md