diff --git a/.github/ISSUE_TEMPLATE/guard-pilot.yml b/.github/ISSUE_TEMPLATE/guard-pilot.yml deleted file mode 100644 index bb9b31a..0000000 --- a/.github/ISSUE_TEMPLATE/guard-pilot.yml +++ /dev/null @@ -1,63 +0,0 @@ -name: GoldKey Guard founding pilot -description: Apply for a scoped, paid enforcement integration pilot. -title: "[Guard pilot] " -body: - - type: markdown - attributes: - value: | - GoldKey Guard founding pilots are **$1,000** for one environment, one connector, one immutable operator policy, and up to two hours of integration support. Successful authorization decisions are billed at **$0.05 for MCP/HTTPS** or **$0.10 for EVM** through x402 on Base. ALLOW, REVIEW, and BLOCK decisions are billable; exact unexpired replays are not. - - This issue is public. Do not include credentials, private keys, wallet seed phrases, confidential payloads, customer data, internal URLs, or proprietary policy contents. - - type: dropdown - id: connector - attributes: - label: Connector type - description: Choose the first execution path you want to enforce. - options: - - MCP tool call - - HTTPS request - - EVM transaction - validations: - required: true - - type: input - id: environment - attributes: - label: Environment - description: A non-secret description such as staging, production canary, or one isolated agent. - placeholder: Production canary for one routing agent - validations: - required: true - - type: textarea - id: problem - attributes: - label: Action that must be enforced - description: Describe the proposed action, the irreversible failure you need to prevent, and how the local enforcer will be the exclusive path. Do not paste real requests or secrets. - placeholder: Prevent unapproved external seller calls before our router forwards credentials or signs a payment. - validations: - required: true - - type: input - id: volume - attributes: - label: Expected monthly authorizations - placeholder: 10,000 - validations: - required: true - - type: dropdown - id: timeline - attributes: - label: Integration timeline - options: - - Within 7 days - - Within 30 days - - More than 30 days - validations: - required: true - - type: checkboxes - id: commercial - attributes: - label: Commercial fit - options: - - label: I understand the $1,000 pilot fee and metered authorization pricing stated above. - required: true - - label: I can run the local enforcer as the exclusive path to the protected credential, connector, or signer. - required: true diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..fcab197 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,51 @@ +name: CI + +"on": + pull_request: + push: + branches: + - main + workflow_dispatch: + +permissions: + contents: read + +jobs: + test: + name: Service, enforcer, and contract tests + runs-on: ubuntu-latest + timeout-minutes: 20 + + steps: + - name: Check out repository + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + with: + persist-credentials: false + + - name: Set up Node.js + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: "22.22.0" + package-manager-cache: false + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@908c540300062bd5a7e473851cdb4282204cee09 # v1.9.1 + with: + version: v1.5.1 + cache: false + + - name: Install script runtime + run: | + sudo apt-get update + sudo apt-get install --yes zsh + + - name: Install locked dependencies + run: | + npm ci + npm --prefix enforcer ci + + - name: Check Solidity formatting + run: forge fmt --root contracts --check + + - name: Run all test suites + run: npm run check diff --git a/LICENSE-MIT b/LICENSE-MIT new file mode 100644 index 0000000..4215f89 --- /dev/null +++ b/LICENSE-MIT @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Noah Ingwers + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 9cc388b..0f50e04 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,107 @@ -# GoldKey +# GoldKey Guard + +GoldKey Guard is an execution-path authorization layer for AI agents. An +operator-controlled local enforcer holds the protected MCP or HTTPS credential, +transport, or signer for supported Base/EVM actions. It forwards a proposed +call only after verifying a short-lived signed `ALLOW` receipt bound to the +exact call, installation, and active operator policy. + +## Security boundary + +Guard is an enforcement boundary only when the agent cannot bypass the local +enforcer to reach the protected capability directly. The hosted authorizer +receives the canonical proposed call, public installation identity and +signature, and any authorization-payment evidence. It does not receive the +protected upstream credential or execution signer, and it never invokes, +signs, broadcasts, or forwards the protected action. + +The fail-closed sequence is: + +1. The operator defines an immutable policy and fixed connector allowlist + outside the agent's control. +2. The local installation canonicalizes and signs the exact proposed call and + durable idempotency key. +3. The hosted authorizer returns a signed `ALLOW`, `REVIEW`, or `BLOCK` decision + bound to the call, installation, policy, and expiry window. +4. The local enforcer verifies that binding and invokes its operator-bound + connector only for a fresh `ALLOW`. `REVIEW` and `BLOCK` never forward. +5. A timeout or crash after forwarding becomes `outcome_unknown`; the enforcer + does not automatically replay an irreversible action. + +The threat model is a compromised or misdirected agent proposing an +unauthorized, altered, over-budget, or replayed action. Guard cannot enforce a +capability that remains reachable through another credential, signer, network +route, or process. Its receipts attest GoldKey's observations and authorization +decision; they do not prove universal safety or an upstream outcome that +GoldKey did not independently observe. See +[GUARD_PRODUCT.md](GUARD_PRODUCT.md) for supported operations, trust +assumptions, adapter limits, DNS and spend controls, and recovery boundaries. + +## Beta status and evidence + +- Guard is a feature-gated design-partner beta. Registration requires an + exactly allowlisted operator wallet, and the hosted routes are disabled by + default until their payment, signing, and allowlist configuration is valid. +- The local enforcer is available as the integrity-pinned + [v0.2.1 beta prerelease](https://github.com/noah-ing/goldkey/releases/tag/v0.2.1). + Verify the attached manifest before installing the tarball. +- The repository includes service, enforcer, and contract tests for policy and + schema drift, exact-call and receipt binding, replay and idempotency, + concurrent spend reservations, destination controls, lifecycle failures, + and supported EVM constraints. +- This beta is not independently audited or certified. It is not a compliance + certification, blanket penetration test, production guarantee, or claim + that every vulnerability will be found or prevented. + +### Verify locally + +Requires Node.js 22 or newer and Foundry: -GoldKey is a fixed-price, transferable NFT access pass sold directly to autonomous agents. +```sh +npm ci +npm --prefix enforcer ci +npm run check +``` + +The two clean installs use the root lockfile and the enforcer's separately +pinned dependency manifest. `npm run check` runs the service/API, +local-enforcer, and Solidity contract test suites. `npm run demo` separately +exercises deterministic quote logic and the prompt scanner without submitting +a transaction. + +Implementation and operating details: + +- [Local enforcer security boundary and installation](enforcer/README.md) +- [Guard product model and non-negotiable security properties](GUARD_PRODUCT.md) +- [Testnet, mainnet, and acceptance runbook](DEPLOYMENT.md) +- [Guarded staging pilot scope and exclusions](SECURITY_PILOT.md) +- [Private vulnerability reporting and supported versions](SECURITY.md) + +## Guarded integration pilot + +GoldKey offers a fixed-fee **$10,000 guarded integration pilot** for teams +preparing to let one AI-agent workflow call a privileged MCP tool, HTTPS +operation, or supported Base/EVM wallet action. The engagement is delivered in +two independently accepted $5,000 milestones and is limited to a customer-owned +staging environment, one workflow, and one connector path. + +The pilot includes a threat model, immutable operator policy, a +customer-controlled local enforcement path, adversarial +allow/deny/replay/drift tests, an evidence package, and an operational handoff. +A smaller $1,000 control-design sprint is available when the integration +boundary is not yet ready to implement. + +See [SECURITY_PILOT.md](SECURITY_PILOT.md) for scope, acceptance criteria, +exclusions, and commercial terms, then use the +[private pilot application](https://goldkey-edge-storefront.noah-ing.workers.dev/#pilot-application) +to describe one concrete workflow and connector. No work begins without +written authorization and a funded milestone. + +## Commerce and deterministic utilities + +Separate from Guard, GoldKey includes an optional fixed-price, transferable +ERC-721 access pass and x402 paygo layer for deterministic agent utilities. The +pass is an API entitlement, not an investment. - Primary price: **50 USDC** - Hard primary supply cap: **10,000** @@ -10,23 +111,18 @@ GoldKey is a fixed-price, transferable NFT access pass sold directly to autonomo - Public alternative: **0.01 USDC per call** through x402 - Mechanical break-even: **5,000 calls per key**, before gas and switching cost -The NFT is not sold on a speculative story. It is the transferable settlement object for a cost-saving API entitlement. At 10,000 calls, paygo costs 100 USDC and GoldKey costs 50 USDC. High-volume orchestrators can issue revocable child-agent keys so an entire swarm draws from one quota. - -The 500,000-USDC figure is the maximum gross from first mints, not a sales forecast and not a cap on total revenue. Renewal and paygo revenue are separate and are not supply-capped. The commercial bottleneck is distribution to agents that genuinely exceed 5,000 eligible calls per term. - -## Paid security integration +At 10,000 calls, paygo costs 100 USDC and the pass costs 50 USDC before gas, +switching cost, and risk reserve. High-volume orchestrators can issue revocable +child-agent keys so multiple workers draw from one quota. The 500,000-USDC +figure is the maximum gross from first mints, not a sales forecast or a cap on +renewal and paygo revenue. -GoldKey also offers a fixed-fee **$10,000 guarded integration pilot** for teams preparing to let one AI-agent workflow call a privileged MCP tool, HTTPS operation, or supported Base/EVM wallet action. The engagement is delivered in two independently accepted $5,000 milestones and is limited to a customer-owned staging environment, one workflow, and one connector path. +GoldKey's four live x402 resources are independently indexed on +[x402scan](https://www.x402scan.com/server/8447beac-d24b-434a-bd01-5abfdab53f84), +including the Action Gate, Agent Utilities, Network Authorization, and EVM +Authorization endpoints. -The pilot includes a threat model, immutable operator policy, a customer-controlled local enforcement path, adversarial allow/deny/replay/drift tests, an evidence package, and an operational handoff. A smaller $1,000 control-design sprint is available when the integration boundary is not yet ready to implement. - -See [SECURITY_PILOT.md](SECURITY_PILOT.md) for scope, acceptance criteria, exclusions, and commercial terms, then use the [private pilot application](https://goldkey-edge-storefront.noah-ing.workers.dev/#pilot-application) to describe one concrete workflow and connector. No work begins without written authorization and a funded milestone. - -GoldKey's four live x402 resources are independently indexed on [x402scan](https://www.x402scan.com/server/8447beac-d24b-434a-bd01-5abfdab53f84), including the Action Gate, Agent Utilities, Network Authorization, and EVM Authorization endpoints. - -The locally tested Guard enforcer is available as an integrity-pinned [v0.2.1 beta prerelease](https://github.com/noah-ing/goldkey/releases/tag/v0.2.1). Verify the attached manifest before installing the local tarball. This beta is not independently audited or certified. - -## What is included +### Included commerce and access controls - Fixed 50-USDC, 10,000-supply ERC-721 contract - Onchain term number, expiration, renewal, immutable price/cap/terms hash @@ -56,21 +152,11 @@ The locally tested Guard enforcer is available as an integrity-pinned [v0.2.1 be Every successful NFT-gated tool result costs one quota unit. Exact NFT-gated idempotent retries are replayed without a second debit. Each paygo request is a separate 0.01-USDC x402 purchase. The service checks the tool name and request shape before payment verification; after verification it fully validates and executes the tool, buffers the result, settles payment, and releases the result only after successful settlement. A tool error cancels settlement. Paygo does not use the NFT idempotency ledger, so retrying a successfully settled paygo call is another purchase. -## Run it +## Run the local service -Requires Node 22 or newer and Foundry for contract tests. - -```sh -npm install -npm run check -npm run demo -``` - -`pg` was added while this workspace had no registry access. The first connected -`npm install` refreshes `package-lock.json`; commit that refreshed lock, then use -`npm ci` for reproducible builds. - -Copy `.env.example` to `.env`, set the RPC and deployed addresses, then: +After the verified install and test sequence above, `npm run demo` runs the +offline quote-and-utility example. To start the API locally, copy `.env.example` +to `.env` and set the RPC and deployed addresses: ```sh npm start @@ -157,8 +243,8 @@ Each input line is a quote request; each output line is a strict JSON commerce r `distribution/goldkey-agent-utilities/` is a ClawHub-ready OpenClaw skill with a no-dependency Node client for discovery, live quotes, authentication, quota, and pass-gated tool calls. Its client pins the verified Base-mainnet Worker, -contract, canonical USDC, and frozen terms hash. Confirm no release placeholders -remain and run its `self-test` before publishing an update. +contract, canonical USDC, and frozen terms hash. Before publishing an update, +run its `self-test` and compare every pinned value with live discovery. Publish the free integration under the `integrations`, `security`, and `finance` categories. The external service remains paid at the posted prices; ClawHub is @@ -214,3 +300,15 @@ See `TERMS.md` for the exact hashed entitlement, `ZERO_CASH_LAUNCH.md` for the capital-free route, `DEPLOYMENT.md` for the complete testnet/mainnet runbook, `edge/README.md` for the always-on storefront, and `CREATE2_DEPLOYMENT.md` for the offline sponsored-deployment manifest builder. + +## License + +Unless a file states otherwise, this repository is distributed under the +[ISC License](LICENSE). The enforcer carries the same ISC text in +[enforcer/LICENSE](enforcer/LICENSE). + +The Solidity contract and its Solidity test declare +`SPDX-License-Identifier: MIT` and are distributed under the +[MIT License](LICENSE-MIT): `contracts/src/GoldKey.sol` and +`contracts/test/GoldKey.t.sol`. Third-party dependencies and generated +dependency metadata retain their own license terms. diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..1193d16 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,66 @@ +# Security Policy + +GoldKey Guard is beta software and has not been independently audited or +certified. Security reports are welcome; this policy does not create a bug +bounty, service-level agreement, or guarantee of payment. + +## Supported versions + +| Component | Status | +|---|---| +| Current main branch and hosted beta | Supported | +| Local enforcer v0.2.1 | Supported | +| Earlier enforcer prereleases | Unsupported; reproduce against v0.2.1 first | + +## Report a vulnerability privately + +Use GitHub's private advisory form: + +https://github.com/noah-ing/goldkey/security/advisories/new + +If that form is unavailable, open a public issue that asks for a private +reporting channel, but include no exploit details, credentials, customer data, +or vulnerable endpoint parameters in the issue. + +Include, when possible: + +- the affected component, version, and commit; +- the security boundary or invariant that can be bypassed; +- minimal reproduction steps using test accounts and testnet assets; +- expected and observed behavior; +- impact, preconditions, and any suggested remediation; and +- whether the issue is already public or under active exploitation. + +Do not test against another person's wallet, installation, data, credentials, +or production workflow. Do not submit irreversible mainnet transactions, +degrade the hosted service, exfiltrate data, or retain data beyond what is +strictly necessary to demonstrate the issue. + +## Priority areas + +High-value reports include: + +- forged, replayed, expired, or incorrectly bound authorization receipts; +- bypasses that let an agent reach a protected connector or signer directly; +- policy, schema, destination, spend, idempotency, or installation-binding + failures; +- extraction of protected upstream credentials or signing material; +- payment or quota accounting errors that create unauthorized execution; and +- transaction-construction flaws that violate documented EVM constraints. + +Reports about expected beta limitations, unsupported deployment topologies, +denial of service without a security boundary bypass, social engineering, or +issues that require prior compromise of the operator-controlled host may be +closed as out of scope. + +## Handling and disclosure + +The maintainer will aim to acknowledge a complete report within three business +days, provide a preliminary assessment within seven business days, and +coordinate remediation and disclosure based on severity and exploitability. +These are targets, not guarantees. + +Please allow a reasonable remediation window before public disclosure. +Good-faith research that follows this policy, minimizes harm, and complies with +applicable law will not be pursued by the maintainer merely for identifying +and privately reporting a vulnerability. diff --git a/edge/public/.well-known/agent-skills/goldkey-agent-utilities.tar.gz b/edge/public/.well-known/agent-skills/goldkey-agent-utilities.tar.gz index e11c41e..a268f3f 100644 Binary files a/edge/public/.well-known/agent-skills/goldkey-agent-utilities.tar.gz and b/edge/public/.well-known/agent-skills/goldkey-agent-utilities.tar.gz differ diff --git a/edge/public/.well-known/agent-skills/index.json b/edge/public/.well-known/agent-skills/index.json index a55078e..1360808 100644 --- a/edge/public/.well-known/agent-skills/index.json +++ b/edge/public/.well-known/agent-skills/index.json @@ -6,7 +6,7 @@ "type": "archive", "description": "Preflight proposed agent actions with GoldKey Action Gate for a deterministic ALLOW, REVIEW, or BLOCK receipt, or integrate the feature-gated GoldKey Guard beta as an operator-controlled enforcement path for actual MCP, HTTPS, AgentCash, or supported Base/EVM calls. Use for x402-paid action screening, policy enforcement before tool calls or wallet transactions, Guard installation and recovery, component JSON, prompt, URL, spend, and Unicode checks, pass-versus-paygo decisions, or GoldKey pass authentication, quota, and scoped child-key operations.", "url": "./goldkey-agent-utilities.tar.gz", - "digest": "sha256:b477e11175562af5af621b064624636d23de33ae31033201a547cc9066092822" + "digest": "sha256:ed5fdb0614a64e874a23b2ace7436b480d6a511ffb38882a27caaea1c11c6b62" } ] } diff --git a/package.json b/package.json index ee61f3c..c49781b 100644 --- a/package.json +++ b/package.json @@ -11,9 +11,9 @@ "dev": "NODE_ENV=development node --watch src/server.mjs", "test": "node --test --test-concurrency=1 test/*.test.mjs", "test:enforcer": "npm --prefix enforcer test", - "test:contract": "/Users/noah-ing/.foundry/bin/forge test --root contracts --offline -vv", - "fmt:contract": "/Users/noah-ing/.foundry/bin/forge fmt --root contracts", - "check": "npm test && npm run test:enforcer && npm run test:contract", + "test:contract": "forge test --root contracts -vv", + "fmt:contract": "forge fmt --root contracts", + "check": "npm run test:contract && npm test && npm run test:enforcer", "deployment:create2": "node scripts/build-create2-deployment.mjs", "deployment:create2:dry-run": "node scripts/build-create2-deployment.mjs --sample-sepolia", "demo": "node scripts/demo.mjs", diff --git a/scripts/build-domain-skill.mjs b/scripts/build-domain-skill.mjs index b70a5df..6dd880b 100644 --- a/scripts/build-domain-skill.mjs +++ b/scripts/build-domain-skill.mjs @@ -3,7 +3,6 @@ import { createHash } from "node:crypto"; import { mkdir, readFile, writeFile } from "node:fs/promises"; import { dirname, resolve } from "node:path"; -import { deflateRawSync } from "node:zlib"; import { fileURLToPath } from "node:url"; const root = resolve(dirname(fileURLToPath(import.meta.url)), ".."); @@ -83,9 +82,50 @@ function crc32(bytes) { return (crc ^ 0xffffffff) >>> 0; } +function reverseBits(value, width) { + let reversed = 0; + for (let bit = 0; bit < width; bit += 1) { + reversed = (reversed << 1) | ((value >>> bit) & 1); + } + return reversed; +} + +function fixedLiteralCode(symbol) { + if (symbol <= 143) return [0x30 + symbol, 8]; + if (symbol <= 255) return [0x190 + symbol - 144, 9]; + if (symbol <= 279) return [symbol - 256, 7]; + return [0xc0 + symbol - 280, 8]; +} + +function deterministicDeflate(bytes) { + const output = []; + let pending = 0; + let pendingBits = 0; + + const writeBits = (value, width) => { + pending |= value << pendingBits; + pendingBits += width; + while (pendingBits >= 8) { + output.push(pending & 0xff); + pending >>>= 8; + pendingBits -= 8; + } + }; + + writeBits(0b011, 3); // final block using the fixed Huffman table + for (const byte of bytes) { + const [code, width] = fixedLiteralCode(byte); + writeBits(reverseBits(code, width), width); + } + const [endCode, endWidth] = fixedLiteralCode(256); + writeBits(reverseBits(endCode, endWidth), endWidth); + if (pendingBits > 0) output.push(pending & 0xff); + return Buffer.from(output); +} + function deterministicGzip(bytes) { - const header = Buffer.from([0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff]); - const compressed = deflateRawSync(bytes, { level: 9 }); + const header = Buffer.from([0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff]); + const compressed = deterministicDeflate(bytes); const trailer = Buffer.alloc(8); trailer.writeUInt32LE(crc32(bytes), 0); trailer.writeUInt32LE(bytes.length >>> 0, 4); diff --git a/src/pilot-applications.mjs b/src/pilot-applications.mjs index ff94728..1400fb1 100644 --- a/src/pilot-applications.mjs +++ b/src/pilot-applications.mjs @@ -105,7 +105,7 @@ function pageLimit(value) { function normalizePublicBody(body) { exactObject(body, PUBLIC_FIELDS, "invalid_pilot_application", "Pilot application"); if (body.budget_confirmed !== true) { - throw new ServiceError(400, "pilot_budget_not_confirmed", "The $1,000 implementation pilot budget must be confirmed"); + throw new ServiceError(400, "pilot_budget_not_confirmed", "The selected engagement budget must be confirmed"); } return { name: text(body.name, "name", { minimum: 2, maximum: 100 }),