web/docs/deployment/secretapi-deploy.md
Joshua b15e13fda5
Some checks are pending
check / secretapi (push) Waiting to run
Harden secretapi sessions and entitlement quote gating
2026-02-19 12:45:46 -08:00

103 lines
3.2 KiB
Markdown

# Secret API Deployment (Staging/Main)
This runbook deploys `web/backend/secretapi` for wallet-first membership and governance install authorization.
## Current edut.dev Runtime
`api.edut.dev` is currently served by the `edut-api` Docker service inside `/opt/edut/gitea/docker-compose.yml` on `edut-prod`.
Routing policy:
1. `api.edut.dev` -> `edut-api:8080`
2. `git.edut.dev` -> Gitea
3. `edut.dev` and `www.edut.dev` -> placeholder response only
Active environment file on host:
1. `/opt/edut/api/.env`
Current test-mode settings:
1. Base Sepolia (`SECRET_API_CHAIN_ID=84532`)
2. ETH quote mode (`SECRET_API_MINT_CURRENCY=ETH`) for low-friction Sepolia smoke validation
3. Membership contract wired to `0x3EEb3342751D1Cfc0F90C9393e0B1cd5AcE6FfD8`
4. Wallet session enforcement enabled by default (`SECRET_API_REQUIRE_WALLET_SESSION=true`)
## Build Targets
1. Native binary:
```bash
cd /Users/vsg/Documents/VSG\ Codex/web/backend/secretapi
go build -o secretapi .
```
2. Container image:
```bash
cd /Users/vsg/Documents/VSG\ Codex/web/backend/secretapi
docker build -t edut/secretapi:latest .
```
## Required Environment
Use `web/backend/secretapi/.env.example` as baseline.
Critical values before launch:
1. `SECRET_API_CHAIN_ID` (`84532` for Base Sepolia, `8453` for Base mainnet)
2. `SECRET_API_CHAIN_RPC_URL`
3. `SECRET_API_VERIFYING_CONTRACT`
4. `SECRET_API_MEMBERSHIP_CONTRACT`
5. Governance package metadata:
- `SECRET_API_GOV_RUNTIME_VERSION`
- `SECRET_API_GOV_PACKAGE_URL`
- `SECRET_API_GOV_PACKAGE_HASH`
- `SECRET_API_GOV_PACKAGE_SIGNATURE`
- `SECRET_API_GOV_SIGNER_KEY_ID`
- `SECRET_API_GOV_POLICY_HASH`
6. Member channel polling:
- `SECRET_API_MEMBER_POLL_INTERVAL_SECONDS`
7. Marketplace contract wiring:
- `SECRET_API_ENTITLEMENT_CONTRACT` must be non-zero for checkout quote issuance
## Systemd Deployment (Hetzner/VPS)
1. Copy binary to `/opt/edut/secretapi/secretapi`.
2. Copy environment file to `/etc/edut/secretapi.env`.
3. Copy unit file `web/backend/secretapi/deploy/secretapi.service` to `/etc/systemd/system/secretapi.service`.
4. Start service:
```bash
sudo systemctl daemon-reload
sudo systemctl enable --now secretapi
sudo systemctl status secretapi
```
## Health Check
```bash
curl -s http://127.0.0.1:8080/healthz
```
Expected:
```json
{"status":"ok"}
```
## Post-Deploy Verification
1. `POST /secret/wallet/intent` returns `intent_id` and `designation_code`.
2. `POST /secret/wallet/verify` accepts valid EIP-712 signature and returns `session_token`.
3. `POST /secret/wallet/session/refresh` rotates wallet session token.
4. `POST /secret/wallet/session/revoke` revokes wallet session token.
5. `POST /secret/membership/quote` returns tx payload.
6. `POST /secret/membership/confirm` marks membership active.
7. `POST /governance/install/token` enforces owner role and active membership.
8. `POST /governance/install/confirm` enforces package/runtime/policy match.
9. `GET /governance/install/status` resolves deterministic activation state.
10. `POST /member/channel/device/register` returns active channel binding.
11. `GET /member/channel/events` returns deterministic inbox page.
12. `POST /member/channel/events/{event_id}/ack` is idempotent per event+device.