Move the hosted MCP handshake to AWS - #93
Merged
Merged
Conversation
Create a guarded one-host AWS provisioner and bootstrap asset so B2 can be replayed without hidden manual steps. Constraint: AWS account 570035913370 in us-west-2; default VPC public subnet; key name clockchain-mcp; SSH limited to executor public /32. Rejected: broad infrastructure framework or reusable module | the task needs one cautious reproducible host provisioner with small repo impact. Confidence: high Scope-risk: narrow Directive: Refuse partial pre-existing B2 resources instead of guessing whether to adopt or mutate them. Tested: bash -n infra/scripts/provision-clockchain-mcp-host.sh infra/scripts/clockchain-mcp-user-data.sh; provisioned EC2/EIP/IAM/SG/SSM resources in AWS; SSH verified cloud-init, Docker hello-world, instance-role SSM read, no /home/ubuntu/.aws; npm test. Not-tested: Application deployment on the host; B3 service/runtime wiring.
Wrap AWS CLI with a disposable HOME and prove the instance-role SSM path during bootstrap so B2 leaves no ~/.aws cache behind. Constraint: B2 requires the literal aws command to work through the EC2 role while /home/ubuntu/.aws remains absent. Rejected: AWS_CONFIG_FILE and AWS_SHARED_CREDENTIALS_FILE redirects | AWS CLI v2 still writes cli/cache/session.db beneath HOME. Confidence: high Scope-risk: narrow Directive: Keep runtime AWS CLI calls behind the disposable-HOME wrapper; do not add static instance credentials. Tested: bash syntax and diff checks; fake CLI cache/exit-status probe; live instance-role PING read with pre/post ~/.aws assertions. Not-tested: Replacement instance bootstrap from a newly provisioned AMI.
The side-by-side stack now fetches SSM secrets without residue, waits for a real MCP healthcheck, and preserves the locked TLS and rate-limit cutover behavior. Constraint: One EC2 host, Docker Compose, Caddy, and SSM Parameter Store are fixed by the execution plan. Rejected: Detached startup without health gating | systemd could report success while MCP was crash-looping. Confidence: high Scope-risk: moderate Directive: Keep production TLS on-demand until its DNS record flips; never expose MCP port 8080 on the host. Tested: root npm test; npm run build; infra 7/7; bash syntax; Compose config; resolved healthcheck execution; Caddy validation. Not-tested: Public test-host TLS awaits the mcp-aws DNS record.
The parity gate now compares bounded health, quota, timestamp, immutable block, and bidirectional ledger semantics before DNS cutover. Constraint: Ambiguous ledger writes must never be retried automatically. Rejected: Shape-only parity | Shape-compatible endpoints can still serve different chain data or security limits. Confidence: high Scope-risk: moderate Directive: Run this gate only with an intentional known block and disposable parity action reference. Tested: parity 17/17; MCP 148/148; npm run build; full npm test. Not-tested: Live AWS endpoint awaits mcp-aws DNS and B3 deployment.
…or risk Constraint: Validator count is explicitly non-blocking for this migration parity run. Rejected: Weakening parity writes by default | production safety must remain fail-closed. Confidence: high Scope-risk: narrow Directive: Use --allow-degraded true only for an explicit operator-approved parity run. Tested: focused parity tests 18/18; MCP package tests 149/149; npm test; npm run build; git diff --check Not-tested: live chain parity pending this commit
Constraint: After the DNS flip both MCP hostnames reach one process keyed by client IP. Rejected: Reusing independent-backend quota deltas | four requests against one bucket move in paired increments. Confidence: high Scope-risk: narrow Directive: Use --shared-backend true only after proving both names resolve to the same service. Tested: focused parity tests 21/21; MCP package tests 152/152; npm test; npm run build; git diff --check Not-tested: live post-cutover parity pending this commit
Constraint: P2 AWS deploy-assets slice limited to external host compose, wrapper secret materialization, and SSM IAM scope in owned infra files only. Rejected: Exposing host ports or exporting host secrets into compose env | the host contract requires no network ingress and file-backed secrets. Confidence: high Scope-risk: narrow Directive: Keep host SecureStrings file-backed under /clockchain/host/* and avoid widening the EC2 SSM resource policy beyond explicit prefixes. Tested: node --test infra/test/deploy-assets.test.mjs; npm test; npm run build; bash -n infra/clockchain-mcp/compose-up.sh; bash -n infra/scripts/provision-clockchain-mcp-host.sh; git diff --check Not-tested: Live AWS provisioning or production docker compose deployment.
The systemd unit runs without sudo's SUDO_UID compatibility hint, so Git must trust only the exact handshake checkout for each validation command. Constraint: The handshake checkout stays owned by the unprivileged deploy user while the compose wrapper runs as root. Rejected: A persistent system-wide safe.directory entry | it adds mutable host configuration outside the reviewed deploy assets. Confidence: high Scope-risk: narrow Directive: Keep safe.directory scoped to HANDSHAKE_APP_ROOT and preserve the clean-checkout SHA guard. Tested: node --test infra/test/deploy-assets.test.mjs; npm test; npm run build; bash -n infra/clockchain-mcp/compose-up.sh; git diff --check; live systemd-shaped Git reproduction on i-0d6765d143da7e1ea. Not-tested: None for this compatibility fix.
Canonical protocol validation, signed relay envelopes, durable principal-scoped state, and read-only EVM verification form the reusable base for MCP orchestration. Constraint: Party keys must remain client-side and relay messages are untrusted coordination data. Rejected: Trusting relay order or persisting party key material | both violate the bilateral authorization boundary. Confidence: high Scope-risk: moderate Directive: Preserve exact canonical wire shapes, bounded RPC reads, and fail-closed replay checks. Tested: MCP package suite passed 236/236; primitive protocol, relay, state, and EVM suites included. Not-tested: Live relay and public EVM behavior are deferred to G3.
Five MCP tools now drive both public roles through signed relay artifacts, verified Clockchain anchors, evidence upload, and certificate retrieval while state stays isolated by the resolved caller principal. Constraint: P3 permits only caller-produced EIP-191 signatures; no party key may touch the server. Rejected: Server-side wallet custody or relay-trusted state transitions | both would erase the intended authority boundary. Confidence: high Scope-risk: broad Directive: Keep the five-tool schema keyless, derive principals from the resolved auth branch, and preserve artifact/descriptor cross-bindings. Tested: MCP package suite passed 236/236; full payer and requestor coordinator flows, retry recovery, degraded override, and certificate checks passed; independent review PASS. Not-tested: Public MCP-to-relay-to-Clockchain G3 remains a live post-deploy gate.
The EC2 compose contract now mounts a named state volume and threads relay, EVM RPC, and explicit degraded-mode configuration through the existing SSM-backed launcher. Constraint: Production may tolerate low validator participation, but source defaults must remain fail-closed. Rejected: Ephemeral container state or a source-level degraded default | either loses sessions or weakens every deployment. Confidence: high Scope-risk: moderate Directive: Enable degraded mode only through an operator-scoped runtime override and keep MCP state on the named volume. Tested: Full monorepo npm test passed; deployment asset suite passed 17/17 including resolved compose and wrapper failure paths. Not-tested: EC2 volume creation and systemd override are verified during the live deployment step.
Constraint: Docker Compose versions render bind metadata as either an empty object or create_host_path metadata. Rejected: Exact resolved JSON deep equality for the bind mount | it made CI version-sensitive without proving deployment safety. Confidence: high Scope-risk: narrow Directive: Assert deployment contracts semantically when Compose injects version-owned metadata. Tested: node --test infra/test/deploy-assets.test.mjs; npm test Not-tested: GitHub Actions rerun on both Node matrix jobs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Verification
npm testacross workspaces and infrastructureDeployment note
Source remains fail-closed for validator cardinality. Production enables the explicit degraded-mode override for the current testnet.