From d3167e9abf328d064b00211c261300e2b541e322 Mon Sep 17 00:00:00 2001 From: farhanqaz Date: Fri, 3 Jul 2026 08:57:06 +0700 Subject: [PATCH] Add authority-surface-ops-skill MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Live on-chain admin surface operations for Solana — mint/freeze/metadata/upgrade authority verification, Squads pre-sign checks, drift detection, launch gate, and weekly ops cadence. Addon for solana-ai-kit; extends solana-dev-skill. Standalone repo: https://github.com/farhanqaz/authority-surface-ops-skill --- .../.github/workflows/ci.yml | 28 +++ authority-surface-ops-skill/.gitignore | 2 + authority-surface-ops-skill/CLAUDE.md | 43 +++++ authority-surface-ops-skill/CONTRIBUTING.md | 24 +++ authority-surface-ops-skill/LICENSE | 21 +++ authority-surface-ops-skill/README.md | 175 ++++++++++++++++++ .../agents/authority-ops-engineer.md | 53 ++++++ .../commands/authority-surface-audit.md | 67 +++++++ .../docs/ARCHITECTURE.md | 48 +++++ authority-surface-ops-skill/docs/CLI.md | 71 +++++++ .../docs/KIT_INTEGRATION.md | 72 +++++++ .../examples/authority-baseline.example.json | 23 +++ .../examples/output/devnet-usdc-report.txt | 28 +++ .../examples/output/ray-mainnet-report.txt | 26 +++ .../output/token-program-upgrade-report.txt | 19 ++ .../examples/reports/README.md | 32 ++++ .../examples/reports/drift-critical-mint.yaml | 31 ++++ .../examples/reports/launch-go-ray.yaml | 25 +++ .../launch-no-go-active-authorities.yaml | 27 +++ .../reports/upgrade-immutable-program.yaml | 19 ++ .../examples/reports/weekly-review-clean.yaml | 23 +++ authority-surface-ops-skill/install.sh | 96 ++++++++++ .../scripts/check-mint-authorities.sh | 144 ++++++++++++++ .../scripts/check-program-upgrade.sh | 124 +++++++++++++ authority-surface-ops-skill/skill/SKILL.md | 142 ++++++++++++++ .../skill/authority-drift.md | 102 ++++++++++ .../skill/incident-handoff.md | 93 ++++++++++ .../skill/launch-checklist.md | 71 +++++++ .../skill/metadata-authority.md | 76 ++++++++ .../skill/mint-freeze-authority.md | 90 +++++++++ .../skill/multisig-verification.md | 94 ++++++++++ .../skill/resources.md | 72 +++++++ .../skill/upgrade-authority.md | 65 +++++++ .../skill/weekly-review.md | 74 ++++++++ authority-surface-ops-skill/validate.sh | 88 +++++++++ 35 files changed, 2188 insertions(+) create mode 100644 authority-surface-ops-skill/.github/workflows/ci.yml create mode 100644 authority-surface-ops-skill/.gitignore create mode 100644 authority-surface-ops-skill/CLAUDE.md create mode 100644 authority-surface-ops-skill/CONTRIBUTING.md create mode 100644 authority-surface-ops-skill/LICENSE create mode 100644 authority-surface-ops-skill/README.md create mode 100644 authority-surface-ops-skill/agents/authority-ops-engineer.md create mode 100644 authority-surface-ops-skill/commands/authority-surface-audit.md create mode 100644 authority-surface-ops-skill/docs/ARCHITECTURE.md create mode 100644 authority-surface-ops-skill/docs/CLI.md create mode 100644 authority-surface-ops-skill/docs/KIT_INTEGRATION.md create mode 100644 authority-surface-ops-skill/examples/authority-baseline.example.json create mode 100644 authority-surface-ops-skill/examples/output/devnet-usdc-report.txt create mode 100644 authority-surface-ops-skill/examples/output/ray-mainnet-report.txt create mode 100644 authority-surface-ops-skill/examples/output/token-program-upgrade-report.txt create mode 100644 authority-surface-ops-skill/examples/reports/README.md create mode 100644 authority-surface-ops-skill/examples/reports/drift-critical-mint.yaml create mode 100644 authority-surface-ops-skill/examples/reports/launch-go-ray.yaml create mode 100644 authority-surface-ops-skill/examples/reports/launch-no-go-active-authorities.yaml create mode 100644 authority-surface-ops-skill/examples/reports/upgrade-immutable-program.yaml create mode 100644 authority-surface-ops-skill/examples/reports/weekly-review-clean.yaml create mode 100755 authority-surface-ops-skill/install.sh create mode 100755 authority-surface-ops-skill/scripts/check-mint-authorities.sh create mode 100755 authority-surface-ops-skill/scripts/check-program-upgrade.sh create mode 100644 authority-surface-ops-skill/skill/SKILL.md create mode 100644 authority-surface-ops-skill/skill/authority-drift.md create mode 100644 authority-surface-ops-skill/skill/incident-handoff.md create mode 100644 authority-surface-ops-skill/skill/launch-checklist.md create mode 100644 authority-surface-ops-skill/skill/metadata-authority.md create mode 100644 authority-surface-ops-skill/skill/mint-freeze-authority.md create mode 100644 authority-surface-ops-skill/skill/multisig-verification.md create mode 100644 authority-surface-ops-skill/skill/resources.md create mode 100644 authority-surface-ops-skill/skill/upgrade-authority.md create mode 100644 authority-surface-ops-skill/skill/weekly-review.md create mode 100755 authority-surface-ops-skill/validate.sh diff --git a/authority-surface-ops-skill/.github/workflows/ci.yml b/authority-surface-ops-skill/.github/workflows/ci.yml new file mode 100644 index 0000000..8d90b54 --- /dev/null +++ b/authority-surface-ops-skill/.github/workflows/ci.yml @@ -0,0 +1,28 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + validate: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Validate skill structure + run: ./validate.sh + + - name: Live mint check (mainnet RAY) + run: | + out=$(./scripts/check-mint-authorities.sh 4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R mainnet-beta) + echo "$out" + echo "$out" | grep -qE 'launch_verdict: ("go"|go)' + + - name: Live program upgrade check (SPL Token) + run: | + out=$(./scripts/check-program-upgrade.sh TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA mainnet-beta) + echo "$out" + echo "$out" | grep -qE 'launch_verdict: ("go"|go)' diff --git a/authority-surface-ops-skill/.gitignore b/authority-surface-ops-skill/.gitignore new file mode 100644 index 0000000..b632020 --- /dev/null +++ b/authority-surface-ops-skill/.gitignore @@ -0,0 +1,2 @@ +.claude/ +*.backup diff --git a/authority-surface-ops-skill/CLAUDE.md b/authority-surface-ops-skill/CLAUDE.md new file mode 100644 index 0000000..24ec615 --- /dev/null +++ b/authority-surface-ops-skill/CLAUDE.md @@ -0,0 +1,43 @@ +# Authority Surface Ops + +Solana **live admin surface operations** addon for Claude Code. Extends [solana-dev-skill](https://github.com/solana-foundation/solana-dev-skill). + +> Audit skills review code before ship. This config covers **mint, freeze, metadata, and upgrade authorities** after deploy. + +## When to load skills + +| User asks… | Read | +|------------|------| +| Mint / freeze authority | `skill/mint-freeze-authority.md` | +| Metadata update authority | `skill/metadata-authority.md` | +| Program upgrade authority | `skill/upgrade-authority.md` | +| Squads pre-sign | `skill/multisig-verification.md` | +| Authority drift | `skill/authority-drift.md` | +| Launch gate | `skill/launch-checklist.md` | +| Weekly review | `skill/weekly-review.md` | +| Authority anomaly | `skill/incident-handoff.md` | + +## Agent & command + +| Task | Use | +|------|-----| +| Full audit workflow | `/authority-surface-audit` | +| Ops execution | `authority-ops-engineer` agent | + +## Rules + +1. Confirm cluster before any mainnet read. +2. Every engagement ends in an **Authority Surface Report** (YAML) — schema in `skill/SKILL.md`. +3. Do not draft public "funds are safe" messages. +4. Launch `go` requires named humans in `signed_off_by`. +5. RPC/decode fails twice → stop and ask. + +## Delegate + +| Need | Route | +|------|-------| +| Source code audit | Trail of Bits / safe-solana-builder | +| Token creation | token-engineer | +| User tx failure | `/debug-user-tx` | + +**Entry point:** [skill/SKILL.md](skill/SKILL.md) diff --git a/authority-surface-ops-skill/CONTRIBUTING.md b/authority-surface-ops-skill/CONTRIBUTING.md new file mode 100644 index 0000000..66e5495 --- /dev/null +++ b/authority-surface-ops-skill/CONTRIBUTING.md @@ -0,0 +1,24 @@ +# Contributing + +Contributions that improve accuracy, Solana ecosystem coverage, or kit compatibility are welcome. + +## Pull requests + +1. Fork the repository and create a feature branch. +2. Run `./validate.sh` before opening a PR. +3. Keep changes focused — one module or concern per PR when possible. +4. Match existing tone: operational, specific, no user-facing financial assurances. + +## Skill modules + +- Update severity rubrics in the relevant `skill/*.md` file. +- Link new modules from `skill/SKILL.md` routing tables. +- Document boundaries in `skill/resources.md` if the change overlaps another kit skill. + +## Reporting issues + +Include cluster, asset type, address (public), and expected vs actual report output. + +## License + +By contributing, you agree that your contributions are licensed under the MIT License. diff --git a/authority-surface-ops-skill/LICENSE b/authority-surface-ops-skill/LICENSE new file mode 100644 index 0000000..9cab89e --- /dev/null +++ b/authority-surface-ops-skill/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Authority Surface Ops Skill contributors + +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/authority-surface-ops-skill/README.md b/authority-surface-ops-skill/README.md new file mode 100644 index 0000000..c9eba5f --- /dev/null +++ b/authority-surface-ops-skill/README.md @@ -0,0 +1,175 @@ +# Authority Surface Ops Skill + +[![CI](https://github.com/farhanqaz/authority-surface-ops-skill/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/farhanqaz/authority-surface-ops-skill/actions/workflows/ci.yml) + +Live on-chain **admin surface operations** for Solana — mint, freeze, metadata, and upgrade authority verification, multisig pre-sign checks, drift detection, and incident handoff. + +> **Addon** for [Solana AI Kit](https://github.com/solanabr/solana-ai-kit) · **Extends** [solana-dev-skill](https://github.com/solana-foundation/solana-dev-skill) + +## Overview + +| Phase | Existing kit coverage | Gap this skill fills | +|-------|----------------------|----------------------| +| Pre-ship | Audit skills review **source code** | — | +| Launch day | token-engineer covers **creation** | — | +| Post-ship | — | **Live authority state** on mints, programs, multisigs | + +``` +┌─────────────────────────────────────────────────────────────┐ +│ authority-surface-ops-skill (addon) │ +│ Launch gate · Weekly review · Drift · Multisig pre-sign │ +│ │ │ +│ ▼ references │ +│ solana-dev-skill · audit skills · token-engineer │ +└─────────────────────────────────────────────────────────────┘ +``` + +## Problem + +After launch, teams often stop checking admin surfaces: + +- Metadata update authority remains on a deployer wallet +- Program upgrade authority stays on a single signer while TVL grows +- Squads proposals are signed without reviewing authority-changing instructions +- Authority changes go unnoticed until users report an issue + +Audit skills review **code before ship**. This skill operates **live admin surfaces after ship**. + +## Modules + +| Surface / workflow | File | +|---------------------|------| +| Mint & freeze authority | `skill/mint-freeze-authority.md` | +| Metadata authority | `skill/metadata-authority.md` | +| Upgrade authority | `skill/upgrade-authority.md` | +| Multisig pre-sign | `skill/multisig-verification.md` | +| Authority drift | `skill/authority-drift.md` | +| Launch week gate | `skill/launch-checklist.md` | +| Weekly review | `skill/weekly-review.md` | +| Incident handoff | `skill/incident-handoff.md` | + +## Installation + +```bash +git clone https://github.com/farhanqaz/authority-surface-ops-skill +cd authority-surface-ops-skill +chmod +x install.sh validate.sh scripts/check-mint-authorities.sh scripts/check-program-upgrade.sh +./install.sh # ~/.claude/skills/ +./install.sh --project # ./.claude/skills/ +./install.sh -y # non-interactive +``` + +Installs skill modules plus `authority-ops-engineer` agent and `/authority-surface-audit` command. Use alongside `solana-dev-skill`. + +### Solana AI Kit submodule + +Maintainers: [docs/KIT_INTEGRATION.md](docs/KIT_INTEGRATION.md) + +## Usage + +``` +Run launch-week authority surface audit for mint and program +``` + +``` +Weekly authority review using baseline at ops/authority-baseline.json +``` + +``` +Verify this Squads proposal before I sign — does it change mint authority? +``` + +``` +Compare current mint authorities against last week's baseline and flag drift +``` + +## Agent & command + +| Asset | Purpose | +|-------|---------| +| `authority-ops-engineer` | Surface reads, checklists, drift diffs, YAML reports | +| `/authority-surface-audit` | End-to-end audit workflow | + +## Output + +Every engagement produces an **Authority Surface Report** (YAML). Schema: `skill/SKILL.md`. + +| Example | Description | +|---------|-------------| +| [examples/reports/](examples/reports/) | Launch, drift, weekly, upgrade samples | +| [examples/output/ray-mainnet-report.txt](examples/output/ray-mainnet-report.txt) | Live RPC — RAY mint | +| [examples/output/token-program-upgrade-report.txt](examples/output/token-program-upgrade-report.txt) | Live RPC — SPL Token program upgrade | +| [examples/output/devnet-usdc-report.txt](examples/output/devnet-usdc-report.txt) | Live RPC — devnet USDC mint | + +Sample output (mainnet RAY, fixed-supply profile): + +```yaml +launch_verdict: go +findings: + - severity: info + observation: "Mint authority revoked (null)" + - severity: info + observation: "Freeze authority revoked (null)" +``` + +## Verified addresses + +| Asset | Address | Cluster | Expected verdict (fixed-supply) | +|-------|---------|---------|--------------------------------| +| RAY | `4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R` | mainnet-beta | `go` | +| SPL Token program | `TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA` | mainnet-beta | Upgrade authority none (immutable) | +| USDC (devnet) | `4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU` | devnet | `no-go` | + +Reproduce: + +```bash +./scripts/check-mint-authorities.sh 4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R mainnet-beta +./scripts/check-program-upgrade.sh TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA mainnet-beta +./scripts/check-mint-authorities.sh 4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU devnet +./scripts/check-mint-authorities.sh EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v mainnet-beta stablecoin +``` + +See [docs/CLI.md](docs/CLI.md). + +## CLI verification + +Read-only RPC helpers (no keys required): + +| Script | Surfaces | +|--------|----------| +| `scripts/check-mint-authorities.sh` | Mint + freeze | +| `scripts/check-program-upgrade.sh` | Program upgrade authority | + +Metadata and Squads checks are agent-driven (Helius DAS / explorer / simulation) — see skill modules. + +```bash +chmod +x scripts/check-mint-authorities.sh scripts/check-program-upgrade.sh +``` + +Live captured output: [`examples/output/`](examples/output/). + +## Validation + +```bash +./validate.sh +``` + +## Scope + +**Included:** Authority verification, launch and weekly cadences, baseline drift, Squads pre-sign review, incident handoff to audit skills. + +**Excluded:** Treasury, payroll, governance voting, compliance, automated monitoring services, end-user transaction support, source-code security audits. + +## Related projects + +- [Solana AI Kit](https://github.com/solanabr/solana-ai-kit) +- [solana-dev-skill](https://github.com/solana-foundation/solana-dev-skill) +- [solana-game-skill](https://github.com/solanabr/solana-game-skill) — structural reference + +## Contributing + +See [CONTRIBUTING.md](CONTRIBUTING.md). Architecture: [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md). + +## License + +MIT — see [LICENSE](LICENSE). diff --git a/authority-surface-ops-skill/agents/authority-ops-engineer.md b/authority-surface-ops-skill/agents/authority-ops-engineer.md new file mode 100644 index 0000000..ac8465b --- /dev/null +++ b/authority-surface-ops-skill/agents/authority-ops-engineer.md @@ -0,0 +1,53 @@ +--- +name: authority-ops-engineer +description: "Authority surface operations specialist. Reads on-chain mint/freeze/metadata/upgrade authorities, verifies multisig proposals before sign, runs launch-week and weekly review checklists, detects authority drift from baselines, and produces structured Authority Surface Reports with incident escalation handoff.\n\nUse when: Launch gate, weekly authority review, verifying Squads proposal affects authorities, investigating unexpected authority change, or producing authority baseline snapshots." +model: sonnet +color: red +--- + +You are the **authority-ops-engineer** — ops-focused, not a code auditor. + +## Skill modules (installed layout) + +- [SKILL.md](../skills/authority-surface-ops/SKILL.md) — routing hub +- [launch-checklist.md](../skills/authority-surface-ops/launch-checklist.md) +- [weekly-review.md](../skills/authority-surface-ops/weekly-review.md) +- [authority-drift.md](../skills/authority-surface-ops/authority-drift.md) +- [incident-handoff.md](../skills/authority-surface-ops/incident-handoff.md) +- [mint-freeze-authority.md](../skills/authority-surface-ops/mint-freeze-authority.md) +- [metadata-authority.md](../skills/authority-surface-ops/metadata-authority.md) +- [upgrade-authority.md](../skills/authority-surface-ops/upgrade-authority.md) +- [multisig-verification.md](../skills/authority-surface-ops/multisig-verification.md) + +Command: `/authority-surface-audit` + +## When to use + +- Launch-week authority gate (T-7 → T+7) +- Weekly 30-minute authority review +- Pre-sign Squads/Realms proposal verification (authority-affecting) +- Drift detection vs baseline JSON +- Authority anomaly → structured incident handoff + +## Delegate to + +| Task | Agent / skill | +|------|----------------| +| Write revoke/upgrade transactions | solana-dev / anchor-engineer | +| Code security review | solana-qa-engineer + Trail of Bits ext | +| Token creation | token-engineer | +| User wallet tx debugging | `/debug-user-tx` workflow | + +## Deliverables + +Always produce **Authority Surface Report** (YAML schema in SKILL.md). Example reports ship in the repo under `examples/reports/`. + +Never: + +- Draft user-facing "funds are safe" messages +- Mark launch `go` with unresolved critical findings +- Sign off on launch gate without named approvers in `signed_off_by` + +## Two-strike rule + +RPC/decode failure twice on same address → STOP, show raw output, request explorer link. diff --git a/authority-surface-ops-skill/commands/authority-surface-audit.md b/authority-surface-ops-skill/commands/authority-surface-audit.md new file mode 100644 index 0000000..135a84f --- /dev/null +++ b/authority-surface-ops-skill/commands/authority-surface-audit.md @@ -0,0 +1,67 @@ +--- +description: "Run structured authority surface audit — mint, freeze, metadata, upgrade, multisig — output Authority Surface Report" +--- + +Run an **Authority Surface Audit** using the **authority-surface-ops** skill. + +## Step 1 — Collect inputs + +Ask if missing: + +1. Cluster (`mainnet-beta` | `devnet`) +2. Asset list: mints, program IDs, multisig vaults +3. Mode: `launch_gate` | `weekly` | `point_check` | `drift` +4. Token model (for mints): `fixed-supply` | `stablecoin` | `program-controlled` +5. Baseline JSON path (required for `drift`) + +## Step 2 — Load skill routing + +Read from `../skills/authority-surface-ops/`: + +1. [SKILL.md](../skills/authority-surface-ops/SKILL.md) — output schema +2. Mode file: + - `launch_gate` → [launch-checklist.md](../skills/authority-surface-ops/launch-checklist.md) + - `weekly` → [weekly-review.md](../skills/authority-surface-ops/weekly-review.md) + - `drift` → [authority-drift.md](../skills/authority-surface-ops/authority-drift.md) + +Compare output structure to `examples/reports/` in this skill when unsure. + +## Step 3 — Surface reads + +For each asset, apply: + +- Mints → [mint-freeze-authority.md](../skills/authority-surface-ops/mint-freeze-authority.md) +- Metadata → [metadata-authority.md](../skills/authority-surface-ops/metadata-authority.md) +- Programs → [upgrade-authority.md](../skills/authority-surface-ops/upgrade-authority.md) +- Pending multisig → [multisig-verification.md](../skills/authority-surface-ops/multisig-verification.md) + +Use RPC / Helius MCP / explorer — list every address checked. + +## Step 4 — Produce report + +Emit YAML **Authority Surface Report**: + +```yaml +report_version: 1 +mode: launch_gate +cluster: mainnet-beta +assets: [...] +findings: [...] +launch_verdict: go | no-go # if launch_gate +drift_summary: {...} # if drift +escalate: none | audit_skill | incident +new_baseline: {...} # if clean review +``` + +## Step 5 — Escalate if needed + +- Any `critical` finding on mainnet → [incident-handoff.md](../skills/authority-surface-ops/incident-handoff.md) +- Code vulnerability suspected → audit skills (do not duplicate audit checklists here) + +## Step 6 — Human signoff + +For `launch_verdict: go`, require named approvers in `signed_off_by`. + +--- + +Do not include: treasury advice, payroll, governance analysis, or public announcement drafts. diff --git a/authority-surface-ops-skill/docs/ARCHITECTURE.md b/authority-surface-ops-skill/docs/ARCHITECTURE.md new file mode 100644 index 0000000..f703b96 --- /dev/null +++ b/authority-surface-ops-skill/docs/ARCHITECTURE.md @@ -0,0 +1,48 @@ +# Architecture + +Progressive-loading skill addon for [Solana AI Kit](https://github.com/solanabr/solana-ai-kit). Follows the same layout as [solana-game-skill](https://github.com/solanabr/solana-game-skill): hub `SKILL.md`, focused module files, optional agent and command definitions. + +## Routing + +``` +Engagement type (SKILL.md) + │ + ├── launch_gate ─── launch-checklist.md + ├── weekly ─────── weekly-review.md → authority-drift.md + ├── drift ──────── authority-drift.md + ├── anomaly ────── incident-handoff.md + └── point_check ── surface module(s) + │ + ├── mint / freeze → mint-freeze-authority.md + ├── metadata ─── metadata-authority.md + ├── upgrade ──── upgrade-authority.md + └── multisig ─── multisig-verification.md + │ + ▼ +Authority Surface Report (YAML) +``` + +## Report schema + +All workflows converge on a single report format (`report_version: 1`) documented in `skill/SKILL.md`. Findings carry severity, affected surface, and optional `blocks_launch` for launch-gate mode. + +## Boundaries + +| Concern | Handled by | +|---------|------------| +| Live authority state | This skill | +| Program / client implementation | solana-dev-skill | +| Token creation | token-engineer (kit) | +| Source-code audit | Trail of Bits, safe-solana-builder | +| User transaction debugging | `/debug-user-tx` (kit) | + +## Design principles + +1. **Progressive disclosure** — hub stays small; modules load on demand. +2. **Ops, not audit** — on-chain state and cadences, not vulnerability scanning. +3. **Human sign-off** — launch verdicts require named approvers; reports are input to decisions, not replacements. +4. **No automated monitoring** — baselines and diffs are manual or agent-driven, not background services. + +## Extension points + +Future modules may cover additional authority-bearing Token-2022 extensions or expanded multisig platforms. Out of scope: treasury, payroll, governance, compliance, and monitoring bots. diff --git a/authority-surface-ops-skill/docs/CLI.md b/authority-surface-ops-skill/docs/CLI.md new file mode 100644 index 0000000..d8db7cc --- /dev/null +++ b/authority-surface-ops-skill/docs/CLI.md @@ -0,0 +1,71 @@ +# CLI reference + +Optional read-only utilities for verifying authorities outside an agent session. + +## check-mint-authorities.sh + +Fetches mint and freeze authority fields via public RPC and prints an Authority Surface Report (YAML). + +### Usage + +```bash +./scripts/check-mint-authorities.sh [cluster] [profile] +``` + +| Argument | Default | Values | +|----------|---------|--------| +| `MINT_ADDRESS` | required | SPL or Token-2022 mint | +| `cluster` | `devnet` | `devnet`, `mainnet-beta` | +| `profile` | `fixed-supply` | `fixed-supply`, `stablecoin` | + +The **profile** selects the rubric from `skill/mint-freeze-authority.md`. Stablecoins (e.g. mainnet USDC) retain mint authority by design — use `stablecoin` to avoid false critical findings. + +### Examples + +Fixed-supply token (revoked authorities): + +```bash +./scripts/check-mint-authorities.sh 4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R mainnet-beta +``` + +Expected: `launch_verdict: go`, informational findings for revoked mint and freeze authorities. + +Token with active authorities: + +```bash +./scripts/check-mint-authorities.sh 4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU devnet +``` + +Expected: `launch_verdict: no-go`, blocking findings when authorities are present on a fixed-supply launch profile. + +## check-program-upgrade.sh + +Reads BPF upgradeable program + ProgramData accounts via public RPC and reports upgrade authority state. + +### Usage + +```bash +./scripts/check-program-upgrade.sh [cluster] +``` + +| Argument | Default | Values | +|----------|---------|--------| +| `PROGRAM_ID` | required | Upgradeable BPF program | +| `cluster` | `mainnet-beta` | `devnet`, `mainnet-beta` | + +### Example + +SPL Token program (immutable deployment): + +```bash +./scripts/check-program-upgrade.sh TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA mainnet-beta +``` + +Expected: `launch_verdict: go`, upgrade authority revoked. + +### Requirements + +- `python3` +- Network access to Solana public RPC endpoints + +No wallet, API keys, or signing capabilities are used. diff --git a/authority-surface-ops-skill/docs/KIT_INTEGRATION.md b/authority-surface-ops-skill/docs/KIT_INTEGRATION.md new file mode 100644 index 0000000..1688c1f --- /dev/null +++ b/authority-surface-ops-skill/docs/KIT_INTEGRATION.md @@ -0,0 +1,72 @@ +# Solana AI Kit integration + +Instructions for maintainers adding this skill as an external submodule to [solana-ai-kit](https://github.com/solanabr/solana-ai-kit). + +## Submodule entry + +Add to `.gitmodules`: + +```ini +[submodule ".claude/skills/ext/authority-surface-ops"] + path = .claude/skills/ext/authority-surface-ops + url = https://github.com/farhanqaz/authority-surface-ops-skill.git +``` + +Initialize: + +```bash +git submodule add https://github.com/farhanqaz/authority-surface-ops-skill.git .claude/skills/ext/authority-surface-ops +git submodule update --init --recursive +``` + +## Hub routing + +Add a row to `.claude/skills/SKILL.md` (kit hub) under an appropriate section: + +```markdown +### Authority surface ops (live admin state) +- [authority-surface-ops/SKILL.md](ext/authority-surface-ops/SKILL.md) — mint/freeze/metadata/upgrade authorities, Squads pre-sign, drift, launch gate +``` + +Suggested trigger keywords for the hub: `mint authority`, `freeze authority`, `upgrade authority`, `authority drift`, `Squads pre-sign`, `launch authority gate`. + +## Agents and commands + +Copy or symlink into the kit tree (same pattern as `solana-game-skill`): + +| Source | Kit destination | +|--------|-----------------| +| `agents/authority-ops-engineer.md` | `.claude/agents/authority-ops-engineer.md` | +| `commands/authority-surface-audit.md` | `.claude/commands/authority-surface-audit.md` | + +Agent and command files reference skill modules at `../skills/authority-surface-ops/` (installed layout). + +## Boundaries vs existing kit skills + +| Need | Route to | +|------|----------| +| Live mint/freeze/metadata/upgrade state | **authority-surface-ops** (this skill) | +| Anchor program source audit | ext/trailofbits, ext/safe-solana-builder | +| Token creation / Token-2022 setup | token-engineer agent | +| User transaction failure | `/debug-user-tx` | +| Program/client implementation | ext/solana-dev | + +Do not duplicate audit checklists or token creation flows in this submodule. + +## Validation + +From the submodule root: + +```bash +./validate.sh +``` + +From kit root after submodule add: + +```bash +./validate.sh # kit validator — confirm hub link resolves +``` + +## License + +MIT — compatible with solana-ai-kit submodule policy. diff --git a/authority-surface-ops-skill/examples/authority-baseline.example.json b/authority-surface-ops-skill/examples/authority-baseline.example.json new file mode 100644 index 0000000..e8c0567 --- /dev/null +++ b/authority-surface-ops-skill/examples/authority-baseline.example.json @@ -0,0 +1,23 @@ +{ + "version": 1, + "cluster": "mainnet-beta", + "captured_at": "2026-06-18T12:00:00Z", + "assets": { + "mints": [ + { + "address": "4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R", + "symbol": "RAY", + "mint_authority": null, + "freeze_authority": null, + "metadata_update_authority": null + } + ], + "programs": [ + { + "program_id": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", + "upgrade_authority": null + } + ], + "multisigs": [] + } +} diff --git a/authority-surface-ops-skill/examples/output/devnet-usdc-report.txt b/authority-surface-ops-skill/examples/output/devnet-usdc-report.txt new file mode 100644 index 0000000..3cc8b48 --- /dev/null +++ b/authority-surface-ops-skill/examples/output/devnet-usdc-report.txt @@ -0,0 +1,28 @@ +report_version: 1 +mode: "point_check" +cluster: "devnet" +token_model: "fixed-supply" +assets: + - + type: "mint" + address: "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU" +findings: + - + id: "F-mint-001" + severity: "high" + surface: "mint" + observation: "Mint authority present: GrNg1XM2ctzeE2mXxXCfhcTUbejM8Z4z4wNVTy2FjMEz" + recommendation: "Revoke or move to multisig before fixed-supply launch" + blocks_launch: True + - + id: "F-freeze-001" + severity: "high" + surface: "freeze" + observation: "Freeze authority present: CJtyoKSLrktozQzjERTiK3btQtiTK3nN4QrqGHLidyCT" + recommendation: "Revoke unless required and held by multisig" + blocks_launch: True +launch_verdict: "no-go" +blocking_findings: + - F-mint-001 + - F-freeze-001 +escalate: "none" diff --git a/authority-surface-ops-skill/examples/output/ray-mainnet-report.txt b/authority-surface-ops-skill/examples/output/ray-mainnet-report.txt new file mode 100644 index 0000000..48961f6 --- /dev/null +++ b/authority-surface-ops-skill/examples/output/ray-mainnet-report.txt @@ -0,0 +1,26 @@ +report_version: 1 +mode: point_check +cluster: mainnet-beta +token_model: fixed-supply +assets: + - + type: mint + address: 4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R +findings: + - + id: F-mint-001 + severity: info + surface: mint + observation: Mint authority revoked (null) + recommendation: No action for fixed-supply model + blocks_launch: false + - + id: F-freeze-001 + severity: info + surface: freeze + observation: Freeze authority revoked (null) + recommendation: No action + blocks_launch: false +launch_verdict: go +blocking_findings: +escalate: none diff --git a/authority-surface-ops-skill/examples/output/token-program-upgrade-report.txt b/authority-surface-ops-skill/examples/output/token-program-upgrade-report.txt new file mode 100644 index 0000000..052f63d --- /dev/null +++ b/authority-surface-ops-skill/examples/output/token-program-upgrade-report.txt @@ -0,0 +1,19 @@ +report_version: 1 +mode: point_check +cluster: mainnet-beta +assets: + - + type: program + address: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA + program_data: 3gvYRKWyXRR9xKWe1ZjPhLY5ZJRN7KDB4rFZFGoJfFk2 +findings: + - + id: F-upg-001 + severity: info + surface: upgrade + observation: Upgrade authority revoked (immutable deployment) + recommendation: Confirm immutability matches team policy + blocks_launch: false +launch_verdict: go +blocking_findings: +escalate: none diff --git a/authority-surface-ops-skill/examples/reports/README.md b/authority-surface-ops-skill/examples/reports/README.md new file mode 100644 index 0000000..3fe6587 --- /dev/null +++ b/authority-surface-ops-skill/examples/reports/README.md @@ -0,0 +1,32 @@ +# Example reports + +Structured **Authority Surface Report** samples. Schema: `skill/SKILL.md`. + +| File | Mode | Scenario | +|------|------|----------| +| [launch-go-ray.yaml](launch-go-ray.yaml) | `launch_gate` | Mainnet RAY — revoked mint/freeze authorities | +| [launch-no-go-active-authorities.yaml](launch-no-go-active-authorities.yaml) | `launch_gate` | Devnet USDC — active mint/freeze authorities under fixed-supply profile | +| [upgrade-immutable-program.yaml](upgrade-immutable-program.yaml) | `point_check` | SPL Token program — upgrade authority revoked | +| [drift-critical-mint.yaml](drift-critical-mint.yaml) | `drift` | Synthetic mint — authority appeared since baseline | +| [weekly-review-clean.yaml](weekly-review-clean.yaml) | `weekly` | No drift, pending multisig noted | + +## Live CLI output + +Read-only RPC verification (fixed-supply launch profile): + +| Asset | Cluster | Output | +|-------|---------|--------| +| RAY `4k3Dyj...` | mainnet-beta | [ray-mainnet-report.txt](../output/ray-mainnet-report.txt) | +| SPL Token program | mainnet-beta | [token-program-upgrade-report.txt](../output/token-program-upgrade-report.txt) | +| USDC devnet `4zMMC9...` | devnet | [devnet-usdc-report.txt](../output/devnet-usdc-report.txt) | + +Regenerate: + +```bash +./scripts/check-mint-authorities.sh 4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R mainnet-beta +./scripts/check-program-upgrade.sh TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA mainnet-beta +``` + +## Baseline sample + +[authority-baseline.example.json](../authority-baseline.example.json) — drift detection input format (`skill/authority-drift.md`). diff --git a/authority-surface-ops-skill/examples/reports/drift-critical-mint.yaml b/authority-surface-ops-skill/examples/reports/drift-critical-mint.yaml new file mode 100644 index 0000000..c9990e4 --- /dev/null +++ b/authority-surface-ops-skill/examples/reports/drift-critical-mint.yaml @@ -0,0 +1,31 @@ +report_version: 1 +mode: drift +cluster: mainnet-beta +generated_at: "2026-06-25T09:00:00Z" +baseline_ref: "ops/authority-baseline-2026-06-18.json" +synthetic: true +assets: + - type: mint + address: "DemoMint1111111111111111111111111111111111" + symbol: DEMO +drift: + - asset: "mint:DemoMint1111..." + field: mint_authority + before: null + after: "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuFoxo7F" + severity: critical + action: incident-handoff +drift_summary: + critical: 1 + high: 0 + unchanged_assets: 0 +recommendation: incident-handoff +new_baseline_required: false +escalate: incident +findings: + - id: F-drift-001 + severity: critical + surface: mint + observation: "Mint authority changed from null to 7xKX... since 2026-06-18 baseline" + recommendation: "Execute incident-handoff.md — freeze signing, preserve evidence" + blocks_launch: true diff --git a/authority-surface-ops-skill/examples/reports/launch-go-ray.yaml b/authority-surface-ops-skill/examples/reports/launch-go-ray.yaml new file mode 100644 index 0000000..57091d8 --- /dev/null +++ b/authority-surface-ops-skill/examples/reports/launch-go-ray.yaml @@ -0,0 +1,25 @@ +report_version: 1 +mode: launch_gate +cluster: mainnet-beta +generated_at: "2026-06-18T12:00:00Z" +assets: + - type: mint + address: "4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R" + symbol: RAY +findings: + - id: F-mint-001 + severity: info + surface: mint + observation: "Mint authority revoked (null)" + recommendation: "No action — fixed supply model satisfied" + blocks_launch: false + - id: F-freeze-001 + severity: info + surface: freeze + observation: "Freeze authority revoked (null)" + recommendation: "No action" + blocks_launch: false +launch_verdict: go +blocking_findings: [] +signed_off_by: [] +escalate: none diff --git a/authority-surface-ops-skill/examples/reports/launch-no-go-active-authorities.yaml b/authority-surface-ops-skill/examples/reports/launch-no-go-active-authorities.yaml new file mode 100644 index 0000000..6b9f66b --- /dev/null +++ b/authority-surface-ops-skill/examples/reports/launch-no-go-active-authorities.yaml @@ -0,0 +1,27 @@ +report_version: 1 +mode: launch_gate +cluster: devnet +generated_at: "2026-06-18T12:00:00Z" +assets: + - type: mint + address: "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU" + symbol: USDC +findings: + - id: F-mint-001 + severity: high + surface: mint + observation: "Mint authority held by GrNg1XM2ctzeE2mXxXCfhcTUbejM8Z4z4wNVTy2FjMEz" + recommendation: "Revoke mint authority or transfer to multisig before a fixed-supply mainnet launch" + blocks_launch: true + - id: F-freeze-001 + severity: high + surface: freeze + observation: "Freeze authority held by CJtyoKSLrktozQzjERTiK3btQtiTK3nN4QrqGHLidyCT" + recommendation: "Revoke unless required and held by documented multisig policy" + blocks_launch: true +launch_verdict: no-go +blocking_findings: + - F-mint-001 + - F-freeze-001 +signed_off_by: [] +escalate: none diff --git a/authority-surface-ops-skill/examples/reports/upgrade-immutable-program.yaml b/authority-surface-ops-skill/examples/reports/upgrade-immutable-program.yaml new file mode 100644 index 0000000..4ac265c --- /dev/null +++ b/authority-surface-ops-skill/examples/reports/upgrade-immutable-program.yaml @@ -0,0 +1,19 @@ +report_version: 1 +mode: point_check +cluster: mainnet-beta +generated_at: "2026-06-18T12:00:00Z" +assets: + - type: program + address: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + name: SPL Token +findings: + - id: F-upg-001 + severity: info + surface: upgrade + observation: "Upgrade authority revoked (Authority: none on ProgramData)" + recommendation: "Immutable deployment — confirm this matches published immutability claims" + blocks_launch: false +launch_verdict: go +blocking_findings: [] +signed_off_by: [] +escalate: none diff --git a/authority-surface-ops-skill/examples/reports/weekly-review-clean.yaml b/authority-surface-ops-skill/examples/reports/weekly-review-clean.yaml new file mode 100644 index 0000000..8d60898 --- /dev/null +++ b/authority-surface-ops-skill/examples/reports/weekly-review-clean.yaml @@ -0,0 +1,23 @@ +report_version: 1 +mode: weekly +cluster: mainnet-beta +generated_at: "2026-06-25T09:30:00Z" +week_of: "2026-W26" +assets_reviewed: 3 +findings: + - id: F-msig-001 + severity: info + surface: multisig + observation: "1 pending Squads proposal — SetAuthority freeze, matches documented Q2 policy" + recommendation: "Run multisig-verification.md before sign" + blocks_launch: false +drift_summary: + critical: 0 + high: 0 + unchanged_assets: 3 +pending_multisig: 1 +weekly_review: + verdict: clean + next_review: "2026-07-02" +escalate: none +new_baseline_required: false diff --git a/authority-surface-ops-skill/install.sh b/authority-surface-ops-skill/install.sh new file mode 100755 index 0000000..07a64e5 --- /dev/null +++ b/authority-surface-ops-skill/install.sh @@ -0,0 +1,96 @@ +#!/usr/bin/env bash +# Authority Surface Ops Skill — standard installer +# Installs skill files into ~/.claude/skills/ (or ./.claude/skills/ with --project) +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SOURCE_DIR="$SCRIPT_DIR/skill" +SKILL_NAME="authority-surface-ops" +TARGET_BASE="${HOME}/.claude/skills" +SKIP_CONFIRM=false +PROJECT=false + +usage() { + cat <\"" +echo "See README.md for usage. Recommended dependency: solana-dev-skill." diff --git a/authority-surface-ops-skill/scripts/check-mint-authorities.sh b/authority-surface-ops-skill/scripts/check-mint-authorities.sh new file mode 100755 index 0000000..9913baa --- /dev/null +++ b/authority-surface-ops-skill/scripts/check-mint-authorities.sh @@ -0,0 +1,144 @@ +#!/usr/bin/env bash +# Read-only mint authority check via public RPC +# Profile: fixed-supply (default) | stablecoin +set -euo pipefail + +MINT="${1:?Usage: check-mint-authorities.sh [cluster] [profile]}" +CLUSTER="${2:-devnet}" +PROFILE="${3:-fixed-supply}" + +case "$CLUSTER" in + mainnet-beta) RPC="https://api.mainnet-beta.solana.com" ;; + devnet) RPC="https://api.devnet.solana.com" ;; + *) echo "Unsupported cluster: $CLUSTER" >&2; exit 1 ;; +esac + +RESP=$(curl -s "$RPC" -X POST -H "Content-Type: application/json" -d "{ + \"jsonrpc\":\"2.0\",\"id\":1, + \"method\":\"getAccountInfo\", + \"params\":[\"$MINT\", {\"encoding\":\"jsonParsed\"}] +}") + +python3 - "$MINT" "$CLUSTER" "$PROFILE" "$RESP" <<'PY' +import json, sys + +mint, cluster, profile, raw = sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4] +data = json.loads(raw) +val = data.get("result", {}).get("value") +if not val: + print("error: account not found", file=sys.stderr) + sys.exit(1) + +parsed = val["data"].get("parsed", {}) +if parsed.get("type") != "mint": + print("error: not a mint account", file=sys.stderr) + sys.exit(1) + +info = parsed["info"] +mint_auth = info.get("mintAuthority") +freeze_auth = info.get("freezeAuthority") + +findings = [] + +if mint_auth: + if profile == "stablecoin": + sev = "info" + blocks = False + rec = "Stablecoin model — verify holder is documented issuer/multisig" + elif cluster == "mainnet-beta": + sev = "critical" + blocks = True + rec = "Revoke or move to multisig before fixed-supply launch" + else: + sev = "high" + blocks = True + rec = "Revoke or move to multisig before fixed-supply launch" + findings.append({ + "id": "F-mint-001", + "severity": sev, + "surface": "mint", + "observation": f"Mint authority present: {mint_auth}", + "recommendation": rec, + "blocks_launch": blocks, + }) +else: + findings.append({ + "id": "F-mint-001", + "severity": "info", + "surface": "mint", + "observation": "Mint authority revoked (null)", + "recommendation": "No action for fixed-supply model", + "blocks_launch": False, + }) + +if freeze_auth: + if profile == "stablecoin": + sev = "info" + blocks = False + rec = "Stablecoin model — verify freeze policy and holder" + else: + sev = "high" + blocks = True + rec = "Revoke unless required and held by multisig" + findings.append({ + "id": "F-freeze-001", + "severity": sev, + "surface": "freeze", + "observation": f"Freeze authority present: {freeze_auth}", + "recommendation": rec, + "blocks_launch": blocks, + }) +else: + findings.append({ + "id": "F-freeze-001", + "severity": "info", + "surface": "freeze", + "observation": "Freeze authority revoked (null)", + "recommendation": "No action", + "blocks_launch": False, + }) + +blocking = [f["id"] for f in findings if f.get("blocks_launch")] +verdict = "no-go" if blocking else "go" + +report = { + "report_version": 1, + "mode": "point_check", + "cluster": cluster, + "token_model": profile, + "assets": [{"type": "mint", "address": mint}], + "findings": findings, + "launch_verdict": verdict, + "blocking_findings": blocking, + "escalate": "incident" if any(f["severity"] == "critical" for f in findings) else "none", +} + +def yaml_val(v): + if isinstance(v, bool): + return "true" if v else "false" + if isinstance(v, str): + if not v or any(c in v for c in ':[]{}#&*!|>\'"\\'): + return json.dumps(v) + return v + return v + +def emit_yaml(obj, indent=0): + sp = " " * indent + if isinstance(obj, dict): + for k, v in obj.items(): + if isinstance(v, (dict, list)): + print(f"{sp}{k}:") + emit_yaml(v, indent + 1) + else: + print(f"{sp}{k}: {yaml_val(v)}") + elif isinstance(obj, list): + for item in obj: + if isinstance(item, dict): + print(f"{sp}-") + for k, v in item.items(): + print(f"{sp} {k}: {yaml_val(v)}") + else: + print(f"{sp}- {item}") + +emit_yaml(report) +PY diff --git a/authority-surface-ops-skill/scripts/check-program-upgrade.sh b/authority-surface-ops-skill/scripts/check-program-upgrade.sh new file mode 100755 index 0000000..d7315eb --- /dev/null +++ b/authority-surface-ops-skill/scripts/check-program-upgrade.sh @@ -0,0 +1,124 @@ +#!/usr/bin/env bash +# Read-only BPF upgrade authority check via public RPC +set -euo pipefail + +PROGRAM="${1:?Usage: check-program-upgrade.sh [cluster]}" +CLUSTER="${2:-mainnet-beta}" + +case "$CLUSTER" in + mainnet-beta) RPC="https://api.mainnet-beta.solana.com" ;; + devnet) RPC="https://api.devnet.solana.com" ;; + *) echo "Unsupported cluster: $CLUSTER" >&2; exit 1 ;; +esac + +export PROGRAM CLUSTER RPC +python3 <<'PY' +import base64, json, os, sys, urllib.request + +program_id = os.environ["PROGRAM"] +cluster = os.environ["CLUSTER"] +rpc = os.environ["RPC"] + +ALPHABET = b"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" + +def b58encode(b: bytes) -> str: + n = int.from_bytes(b, "big") + res = bytearray() + while n > 0: + n, r = divmod(n, 58) + res.insert(0, ALPHABET[r]) + pad = len(b) - len(b.lstrip(b"\0")) + return (ALPHABET[0:1] * pad + res).decode() + +def rpc_call(addr: str) -> dict: + body = json.dumps({ + "jsonrpc": "2.0", "id": 1, + "method": "getAccountInfo", + "params": [addr, {"encoding": "base64"}], + }).encode() + req = urllib.request.Request(rpc, data=body, headers={"Content-Type": "application/json"}) + with urllib.request.urlopen(req, timeout=30) as resp: + return json.loads(resp.read()) + +prog = rpc_call(program_id)["result"]["value"] +if not prog: + print("error: program account not found", file=sys.stderr) + sys.exit(1) + +if prog["owner"] != "BPFLoaderUpgradeab1e11111111111111111111111": + print("error: not upgradeable BPF (owner: %s)" % prog["owner"], file=sys.stderr) + sys.exit(1) + +prog_bytes = base64.b64decode(prog["data"][0]) +pd_addr = b58encode(prog_bytes[4:36]) + +pd = rpc_call(pd_addr)["result"]["value"] +if not pd: + print("error: program data account not found", file=sys.stderr) + sys.exit(1) + +pd_bytes = base64.b64decode(pd["data"][0]) +# ProgramData: u32 tag (3) + u64 slot + COption (1 tag + 32 key) +tag = pd_bytes[12] +if tag == 0: + upgrade_auth = None + obs = "Upgrade authority revoked (immutable deployment)" + sev = "info" + blocks = False + rec = "Confirm immutability matches team policy" +else: + upgrade_auth = b58encode(pd_bytes[13:45]) + obs = f"Upgrade authority present: {upgrade_auth}" + sev = "critical" if cluster == "mainnet-beta" else "high" + blocks = True + rec = "Transfer to multisig or revoke before accepting external TVL" + +findings = [{ + "id": "F-upg-001", + "severity": sev, + "surface": "upgrade", + "observation": obs, + "recommendation": rec, + "blocks_launch": blocks, +}] +blocking = [f["id"] for f in findings if f["blocks_launch"]] +report = { + "report_version": 1, + "mode": "point_check", + "cluster": cluster, + "assets": [{"type": "program", "address": program_id, "program_data": pd_addr}], + "findings": findings, + "launch_verdict": "no-go" if blocking else "go", + "blocking_findings": blocking, + "escalate": "incident" if sev == "critical" else "none", +} + +def yaml_val(v): + if isinstance(v, bool): + return "true" if v else "false" + if isinstance(v, str): + if not v or any(c in v for c in ':[]{}#&*!|>\'"\\'): + return json.dumps(v) + return v + return v + +def emit_yaml(obj, indent=0): + sp = " " * indent + if isinstance(obj, dict): + for k, v in obj.items(): + if isinstance(v, (dict, list)): + print(f"{sp}{k}:") + emit_yaml(v, indent + 1) + else: + print(f"{sp}{k}: {yaml_val(v)}") + elif isinstance(obj, list): + for item in obj: + if isinstance(item, dict): + print(f"{sp}-") + for k, v in item.items(): + print(f"{sp} {k}: {yaml_val(v)}") + else: + print(f"{sp}- {item}") + +emit_yaml(report) +PY diff --git a/authority-surface-ops-skill/skill/SKILL.md b/authority-surface-ops-skill/skill/SKILL.md new file mode 100644 index 0000000..eef686d --- /dev/null +++ b/authority-surface-ops-skill/skill/SKILL.md @@ -0,0 +1,142 @@ +--- +name: authority-surface-ops +description: Live on-chain admin surface operations for Solana builders — mint/freeze/metadata/upgrade authority verification, multisig pre-sign checks, authority drift detection, launch-week and weekly review cadences, and incident escalation handoff. Extends solana-dev-skill for ops; does NOT replace security audits or token creation. +user-invocable: true +--- + +# Authority Surface Ops Skill + +> **Extends**: [solana-dev-skill](https://github.com/solana-foundation/solana-dev-skill) for program/client context only. +> **Does NOT replace**: Trail of Bits / safe-solana-builder (code audit), token-engineer (token creation). + +## What This Skill Is For + +Use when the user asks about **live admin surfaces on-chain** — not how to write programs. + +## When NOT to Use (route elsewhere) + +| User need | Route to | +|-----------|----------| +| Audit Anchor/Rust source code | Trail of Bits / safe-solana-builder / solana-dev → security.md | +| Create or configure a token | token-engineer / solana-dev | +| Debug a user's failed wallet transaction | `/debug-user-tx` (kit) | +| Treasury runway or payroll | Out of scope | +| DAO governance voting strategy | Out of scope | + +Example reports: [examples/reports/](https://github.com/farhanqaz/authority-surface-ops-skill/tree/main/examples/reports) + +| Trigger phrases | Route to | +|-----------------|----------| +| "revoke mint authority", "who can mint", "freeze authority" | [mint-freeze-authority.md](mint-freeze-authority.md) | +| "metadata authority", "update URI", "Metaplex authority" | [metadata-authority.md](metadata-authority.md) | +| "upgrade authority", "program upgradeable", "immutable program" | [upgrade-authority.md](upgrade-authority.md) | +| "Squads before sign", "multisig verification", "Realms proposal" | [multisig-verification.md](multisig-verification.md) | +| "authority changed", "drift", "diff since last week" | [authority-drift.md](authority-drift.md) | +| "launch checklist", "before mainnet", "day-0 authorities" | [launch-checklist.md](launch-checklist.md) | +| "weekly authority review", "ops cadence" | [weekly-review.md](weekly-review.md) | +| "authority anomaly", "possible exploit", "escalate" | [incident-handoff.md](incident-handoff.md) | + +## Default Stack (January 2026) + +| Surface | Where it lives | Read via | +|---------|----------------|----------| +| SPL mint/freeze | Mint account | `getAccountInfo` + SPL layout / explorer | +| Token-2022 mint/freeze | Mint account (Token-2022 program) | Same + extension scan | +| Metadata (Metaplex) | Metadata PDA | DAS or Metaplex decode | +| Program upgrade | Program account + ProgramData | `getAccountInfo` on program ID | +| Multisig custody | Squads v4 / Realms | Explorer + proposal simulation | + +**Clusters**: Always confirm `mainnet-beta` vs `devnet`. Never assume. + +## Operating Procedure + +### 1. Classify the engagement + +| Mode | When | Primary files | +|------|------|---------------| +| **Launch gate** | Pre-mainnet or launch week | launch-checklist.md → surface-specific files | +| **Weekly ops** | Recurring review | weekly-review.md → authority-drift.md | +| **Point check** | Single mint/program/multisig | Surface-specific file | +| **Anomaly** | Unexpected change detected | incident-handoff.md first | + +### 2. Collect minimum inputs + +Always ask or infer: + +- Cluster +- Asset type: `mint` | `program` | `multisig_proposal` +- Address(es) +- Baseline snapshot (if drift review) — prior JSON or "first review" + +### 3. Produce structured output + +Every engagement ends with an **Authority Surface Report**: + +```yaml +report_version: 1 +cluster: mainnet-beta +assets: [...] +findings: + - id: F-001 + severity: critical | high | medium | low | info + surface: mint | freeze | metadata | upgrade | multisig + observation: "" + recommendation: "" + blocks_launch: true | false +escalate: none | audit_skill | incident +``` + +Do **not** draft public announcements or user-facing "your funds are safe" messages. + +### 4. Escalation rules + +| Condition | Action | +|-----------|--------| +| Critical finding + live mainnet | [incident-handoff.md](incident-handoff.md) | +| Code-level vulnerability suspected | Delegate to solana-dev → security.md or Trail of Bits ext skill | +| Token creation / extensions setup | Delegate to token-engineer (kit agent) | + +### 5. Two-strike rule + +If RPC/decode fails twice on the same address: STOP, show raw response, ask user for explorer link or corrected address. + +--- + +## Progressive Disclosure + +### Surface modules +- [mint-freeze-authority.md](mint-freeze-authority.md) — SPL + Token-2022 mint & freeze holders +- [metadata-authority.md](metadata-authority.md) — Metaplex metadata update authority +- [upgrade-authority.md](upgrade-authority.md) — BPF upgrade authority & immutability +- [multisig-verification.md](multisig-verification.md) — Pre-sign verification for Squads/Realms + +### Ops cadences +- [launch-checklist.md](launch-checklist.md) — Launch week gate (day -7 → day +7) +- [weekly-review.md](weekly-review.md) — 30-minute weekly review script +- [authority-drift.md](authority-drift.md) — Baseline diff methodology + +### Escalation +- [incident-handoff.md](incident-handoff.md) — Anomaly → war room → audit skills + +### Reference +- [resources.md](resources.md) — Program IDs, RPC patterns, snapshot schema + +--- + +## Commands & Agents + +| Command | Description | +|---------|-------------| +| `/authority-surface-audit` | Structured audit → Authority Surface Report | + +| Agent | Purpose | +|-------|---------| +| **authority-ops-engineer** | Executes surface reads, checklists, drift diffs, reports | + +--- + +## Out of scope + +Treasury runway, payroll, governance voting, tax/compliance, automated monitoring bots, user transaction support triage, source-code security audits. + +See [resources.md](resources.md) for boundaries vs other kit skills. diff --git a/authority-surface-ops-skill/skill/authority-drift.md b/authority-surface-ops-skill/skill/authority-drift.md new file mode 100644 index 0000000..34db201 --- /dev/null +++ b/authority-surface-ops-skill/skill/authority-drift.md @@ -0,0 +1,102 @@ +# Authority Drift Detection + +Detect changes to admin surfaces since a saved baseline. + +## Purpose + +Weekly ops and incident triage: **what changed?** without automated bots — manual/agent-driven diff. + +## Baseline snapshot schema + +Store after launch gate or each weekly review (`authority-baseline.json` in repo — **not** secrets): + +```json +{ + "version": 1, + "cluster": "mainnet-beta", + "captured_at": "2026-06-18T12:00:00Z", + "assets": { + "mints": [ + { + "address": "...", + "mint_authority": null, + "freeze_authority": null, + "metadata_update_authority": "..." + } + ], + "programs": [ + { + "program_id": "...", + "upgrade_authority": "..." + } + ], + "multisigs": [ + { + "vault": "...", + "threshold": 2, + "members": ["...", "..."] + } + ] + } +} +``` + +## Drift procedure + +1. Load latest baseline (user provides path or paste). +2. Re-read all surfaces using surface modules. +3. Emit diff: + +```yaml +drift: + - asset: mint:... + field: mint_authority + before: null + after: "7xKX..." + severity: critical + action: incident-handoff + - asset: program:... + field: upgrade_authority + before: "SquadsVault..." + after: "SquadsVault..." + severity: none +``` + +## Severity for unexpected changes + +| Change | Severity | +|--------|----------| +| Any authority null → non-null | **critical** | +| Authority holder pubkey changed | **critical** | +| Multisig member added/removed | **high** | +| Metadata URI changed | **high** (if not scheduled) | +| Supply increased | **critical** | +| Threshold lowered | **critical** | + +## First review (no baseline) + +- Run [launch-checklist.md](launch-checklist.md) or [weekly-review.md](weekly-review.md) +- **Create baseline** as deliverable — do not skip + +## Storage guidance + +- Commit baseline to private repo or password manager attachment +- Never commit private keys; pubkeys only +- Date baseline files: `authority-baseline-2026-06-18.json` + +## Output + +Always include: + +```yaml +drift_summary: + critical: 0 + high: 0 + unchanged_assets: 3 +recommendation: continue | weekly_only | incident-handoff +new_baseline_required: true +``` + +## Delegation + +- If drift + user funds at risk → [incident-handoff.md](incident-handoff.md) diff --git a/authority-surface-ops-skill/skill/incident-handoff.md b/authority-surface-ops-skill/skill/incident-handoff.md new file mode 100644 index 0000000..20d5238 --- /dev/null +++ b/authority-surface-ops-skill/skill/incident-handoff.md @@ -0,0 +1,93 @@ +# Incident Escalation Handoff + +Authority **anomaly** response — internal ops only. Not public comms. + +## Trigger conditions + +Enter this flow when any of: + +- Drift diff shows `critical` authority change +- Unexpected mint supply increase +- Upgrade authority exercised without release tag +- Multisig member/threshold changed without approval +- Mint/freeze authority moved to unknown pubkey + +## First 15 minutes + +### 1. Freeze human actions + +- [ ] **Stop signing** pending multisig proposals +- [ ] Do not publish "all clear" statements +- [ ] Assign incident lead (human) + scribe + +### 2. Preserve evidence + +Capture immediately: + +```yaml +evidence: + cluster: mainnet-beta + detected_at: + affected_assets: [] + explorer_links: [] + baseline_snapshot_ref: + current_read: + recent_proposals: [] # Squads URLs +``` + +### 3. Classify severity + +| Level | Criteria | Example | +|-------|----------|---------| +| **SEV-0** | Active drain or mint in progress | Live mint from compromised authority | +| **SEV-1** | Authority compromised, no drain yet | Upgrade key on attacker wallet | +| **SEV-2** | Suspicious but unconfirmed | URI changed, supply unchanged | +| **SEV-3** | False alarm / scheduled change missed in baseline | Planned metadata update | + +### 4. Containment (authority-specific) + +| Surface | Immediate action | +|---------|------------------| +| Mint authority hot | Revoke if still reachable; pause minting frontend | +| Upgrade authority hot | Do not deploy; assess malicious upgrade tx in mempool/explorer | +| Multisig compromised | Contact other signers; do not approve pending txs | +| Metadata changed | Document URI diff; assess phishing risk separately | + +This skill does **not** provide exploit remediation code. + +## Handoff map + +| Need | Route to | +|------|----------| +| Code vulnerability / malicious program logic | solana-dev → security.md + Trail of Bits ext | +| Formal property check | QEDGen ext skill | +| Transaction forensics (user impact) | `/debug-user-tx` (kit command) — supplemental only | +| Full audit engagement | External auditor — use prior reports as context | + +## Internal status template + +```yaml +incident: + id: INC-2026-001 + severity: SEV-1 + status: investigating | contained | resolved | false_alarm + authority_surfaces: [mint, upgrade] + owner: + next_update: +30min + public_comms: none # determined by incident lead / legal +``` + +## Exit criteria + +- [ ] Root cause identified (compromise vs ops mistake vs scheduled) +- [ ] Authorities restored or revoked to known-good state +- [ ] New baseline captured +- [ ] Post-incident entry in weekly review notes +- [ ] Optional: schedule code audit if upgrade authority was involved + +## Out of scope + +- Twitter/Discord announcement drafts +- Law enforcement / legal +- Insurance claims +- On-chain counter-exploits diff --git a/authority-surface-ops-skill/skill/launch-checklist.md b/authority-surface-ops-skill/skill/launch-checklist.md new file mode 100644 index 0000000..afa4dd8 --- /dev/null +++ b/authority-surface-ops-skill/skill/launch-checklist.md @@ -0,0 +1,71 @@ +# Launch Week Checklist + +Authority surface gate from **T-7** through **T+7** (mainnet). + +## Inputs required + +- Cluster (must be explicit before mainnet steps) +- Mint address(es) +- Program ID(s) +- Multisig vault address(es) +- Intended token model (fixed supply / upgradeable program / etc.) + +## T-7 — Design alignment + +- [ ] Document intended final state for each surface (mint, freeze, metadata, upgrade) +- [ ] Map each surface to expected holder (revoked | multisig | program PDA) +- [ ] Review with a second approver — automated checks alone are insufficient + +## T-3 — Devnet / staging proof + +- [ ] Run full surface read on staging assets +- [ ] Execute dry-run revoke/transfer txs on devnet mirroring mainnet plan +- [ ] Save devnet baseline for comparison + +## T-0 — Pre-launch gate (blocks launch) + +Run modules in order: + +1. [mint-freeze-authority.md](mint-freeze-authority.md) — all mints +2. [metadata-authority.md](metadata-authority.md) — all collections +3. [upgrade-authority.md](upgrade-authority.md) — all programs +4. [multisig-verification.md](multisig-verification.md) — any pending authority txs + +### Hard stop conditions (`blocks_launch: true`) + +- Mint authority on hot wallet for fixed-supply token +- Freeze authority on unrecognized key +- Upgrade authority on single signer with TVL expected +- Metadata mutable on deployer wallet without documented plan +- Any pending Squads proposal transferring authority to unknown key + +**Deliverable**: Authority Surface Report with `launch_verdict: go | no-go` + +## T+0 — Launch window (first 24h) + +- [ ] Re-read all surfaces 6h and 24h post-launch +- [ ] Compare to T-0 report — any drift → [incident-handoff.md](incident-handoff.md) +- [ ] Capture **mainnet baseline** JSON ([authority-drift.md](authority-drift.md)) + +## T+7 — Launch week close + +- [ ] Confirm final authority state matches public commitments (site/docs) +- [ ] Revoke or transfer any remaining temporary authorities +- [ ] Archive launch report + baseline in team repo +- [ ] Schedule recurring [weekly-review.md](weekly-review.md) + +## Launch verdict template + +```yaml +launch_verdict: no-go +blocking_findings: + - F-mint-001 + - F-upg-001 +signed_off_by: [] # named approvers required before launch +next_review: T+0 + 6h +``` + +## Delegation + +- Token deployment steps → token-engineer / solana-dev +- Marketing copy about "immutable" → not this skill diff --git a/authority-surface-ops-skill/skill/metadata-authority.md b/authority-surface-ops-skill/skill/metadata-authority.md new file mode 100644 index 0000000..1c906d3 --- /dev/null +++ b/authority-surface-ops-skill/skill/metadata-authority.md @@ -0,0 +1,76 @@ +# Metadata Authority + +Verify who can change token name, symbol, URI, and seller fee basis points. + +## Applies to + +- Metaplex Token Metadata (legacy) +- Metaplex Core assets (different model — flag asset type first) + +## Read procedure + +1. Confirm mint address and cluster. +2. Derive metadata PDA (Token Metadata program): + +``` +seeds = ["metadata", TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA, ] +program = metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s +``` + +3. Fetch metadata account (Helius DAS `getAsset` with mint or metadata address, or explorer decode). +4. Record: + +```yaml +metadata_account:
+mint:
+update_authority: + holder: + is_mutable: true | false +primary_sale_happened: true | false +seller_fee_basis_points: +uri: +``` + +## Severity rubric + +| State | Severity | blocks_launch | +|-------|----------|---------------| +| Update authority on deployer hot wallet post-launch | **high** | true | +| `is_mutable: true` after "immutable collection" marketing | medium | review | +| Update authority = program PDA (expected for dynamic NFT) | info | false | +| Update authority revoked / immutable | info | false | +| URI points to centralized server without backup plan | medium | review | + +## Launch-week expectations + +| Asset type | Typical update authority | +|------------|-------------------------| +| Fixed art PFP | Revoked or burned after reveal | +| Dynamic/game item | Program PDA | +| Collection with ongoing drops | Multisig | + +## Relationship to mint authority + +These are **independent surfaces**. A token can have: + +- Revoked mint + **live** metadata authority (URI rug vector) +- Live mint + revoked metadata + +Always report both in launch gate. + +## Output snippet + +```yaml +findings: + - id: F-meta-001 + severity: high + surface: metadata + observation: "Update authority 9abc... matches deployer wallet" + recommendation: "Transfer to multisig or revoke after metadata freeze" + blocks_launch: true +``` + +## Delegation + +- Metaplex minting/integration patterns → ext/metaplex skill (kit) +- On-chain metadata program code → solana-dev → programs-anchor.md diff --git a/authority-surface-ops-skill/skill/mint-freeze-authority.md b/authority-surface-ops-skill/skill/mint-freeze-authority.md new file mode 100644 index 0000000..b9a18df --- /dev/null +++ b/authority-surface-ops-skill/skill/mint-freeze-authority.md @@ -0,0 +1,90 @@ +# Mint & Freeze Authority + +Verify who can inflate supply and who can freeze token accounts. + +## Applies to + +- SPL Token (`TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA`) +- Token-2022 (`TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb`) + +## Read procedure + +1. Confirm cluster and mint address. +2. Fetch mint account (`getAccountInfo`, jsonParsed preferred). +3. Record: + +```yaml +mint:
+program: spl-token | token-2022 +supply: +decimals: +mint_authority: + present: true | false + holder: +freeze_authority: + present: true | false + holder: +is_initialized: true +extensions: [] # Token-2022 only — list active extensions +``` + +4. For Token-2022, scan extensions that add **secondary authorities** (transfer hook, permanent delegate, etc.) — flag any unexpected authority-bearing extension as **high**. + +## Severity rubric + +| State | Severity | blocks_launch | +|-------|----------|---------------| +| Mint authority on hot wallet / single EOA | **critical** | true | +| Mint authority present after "fixed supply" claim | **critical** | true | +| Mint authority on multisig (expected) | info | false | +| Mint authority revoked (`null`) | info | false (desired for fixed supply) | +| Freeze authority on unknown key | **high** | true | +| Freeze authority retained "for compliance" without doc | medium | review | +| Freeze authority revoked | info | false (usually desired) | + +## Launch-week expectations + +| Token model | Mint authority | Freeze authority | +|-------------|----------------|------------------| +| Fixed supply meme/token | **Revoked** | Revoked (typical) | +| Stablecoin / RWA | Multisig + timelock | Multisig (if used) | +| Gaming consumable | Program PDA or multisig | Usually revoked | + +## Known production patterns + +| Mint | Mint authority | Interpretation | +|------|----------------|----------------| +| RAY `4k3Dyj...` | `null` | Fixed supply — launch gate pass | +| USDC `EPjFWdd5...` | Circle-controlled key | **Expected** for stablecoin mint/burn — use `stablecoin` token model, not fixed-supply rubric | +| Devnet test mint | Deployer wallet | Expected on devnet; **never** treat as mainnet launch pass | + +Always confirm **token model** before applying `blocks_launch`. A present mint authority is critical for fixed-supply launches and informational for stablecoins on documented multisig/holder keys. + +## Multisig as holder + +If holder is a Squads vault / multisig: + +1. Do **not** mark safe without [multisig-verification.md](multisig-verification.md). +2. Record vault address and threshold if visible on explorer. + +## Common false positives + +- User confuses **mint authority** with **update authority** (metadata) — cross-check [metadata-authority.md](metadata-authority.md). +- Devnet mint with open authority — OK on devnet, **never** extrapolate to mainnet. + +## Output snippet + +```yaml +findings: + - id: F-mint-001 + severity: critical + surface: mint + observation: "Mint authority held by 7xKX... (single signer wallet)" + recommendation: "Revoke or transfer to Squads vault before mainnet launch" + blocks_launch: true +``` + +## Delegation + +- Writing revoke instructions → solana-dev-skill (client tx building) +- Code allowing unauthorized mint → solana-dev → security.md diff --git a/authority-surface-ops-skill/skill/multisig-verification.md b/authority-surface-ops-skill/skill/multisig-verification.md new file mode 100644 index 0000000..b136104 --- /dev/null +++ b/authority-surface-ops-skill/skill/multisig-verification.md @@ -0,0 +1,94 @@ +# Multisig Verification + +Pre-sign verification for Squads and Realms proposals that touch authorities. + +## Scope + +- **Squads v4** vault transactions (most common founder multisig) +- **Realms** governance accounts (authority holder identification only — not governance ops) + +Squads v4 multisig program (mainnet): `SQDS4ep65FkdopVRP8tqisRmT6ksGF2hqZ6j12GuLT` + +Out of scope: proposal creation, payroll, voting strategy. + +## Verify vault identity + +Before decoding instructions: + +1. Confirm the vault address in the Squads UI matches your documented baseline (`authority-baseline.json` → `multisigs[]`). +2. On explorer, verify vault account **owner** is the Squads program ID above. +3. Compare member set and threshold to baseline — any drift is **high** until explained. + +```bash +solana account --output json --url mainnet-beta +# owner must be SQDS4ep65FkdopVRP8tqisRmT6ksGF2hqZ6j12GuLT +``` + +## Pre-sign checklist + +Before user signs in Phantom/Squads UI: + +### 1. Identity + +- [ ] Proposal URL / vault address matches team's **documented** multisig +- [ ] Threshold and members match last approved baseline (see [authority-drift.md](authority-drift.md)) + +### 2. Instruction decode + +For each instruction in the proposal: + +| Instruction pattern | Verify | +|--------------------|--------| +| `SetAuthority` (mint) | New authority is intended recipient; not EOA unless documented | +| `SetAuthority` (freeze) | Same | +| Metadata update | URI/signer expected | +| `Upgrade` / buffer deploy | Matches scheduled release tag | +| SOL/token transfer | Recipient labeled in internal runbook | + +### 3. Simulation + +- [ ] Simulate proposal on correct cluster +- [ ] Post-simulation token balances / authorities match intent +- [ ] No unexpected inner instructions (CPI to unknown program → **stop**) + +### 4. Diff against baseline + +- [ ] If proposal changes any authority field, require second reviewer (human) +- [ ] Compare to [launch-checklist.md](launch-checklist.md) approved state + +## Severity rubric + +| State | Severity | +|-------|----------| +| Unknown program in CPI chain | **critical** — do not sign | +| Authority transferred to unrecognized pubkey | **critical** | +| Mint/freeze revoke mismatch with stated intent | **high** | +| Simulation fails | **high** — do not sign until eng review | + +## Squads-specific notes + +- Vault PDA ≠ member wallet — always audit **vault transaction effects** +- Draft proposals can be edited — re-verify hash/instructions immediately before sign + +## Realms-specific notes + +- Use Realms to **identify** who holds program/token authorities +- Do not analyze vote economics or proposal politics + +## Output snippet + +```yaml +findings: + - id: F-msig-001 + severity: critical + surface: multisig + observation: "Proposal includes SetAuthority mint → unknown EOA 8xyz..." + recommendation: "Reject signature; open internal review" + blocks_launch: false +multisig_verdict: reject | approve_with_notes | needs_second_reviewer +``` + +## Delegation + +- Building Squads txs → solana-dev client patterns +- Smart contract logic in proposal → audit skills diff --git a/authority-surface-ops-skill/skill/resources.md b/authority-surface-ops-skill/skill/resources.md new file mode 100644 index 0000000..444fb64 --- /dev/null +++ b/authority-surface-ops-skill/skill/resources.md @@ -0,0 +1,72 @@ +# Resources + +## Positioning + +| Phase | Kit skill | +|-------|-----------| +| Write / audit program code | solana-dev, Trail of Bits, safe-solana-builder | +| Create token, configure extensions | token-engineer | +| **Operate live admin authorities after deploy** | **authority-surface-ops (this skill)** | +| User tx failed in production | `/debug-user-tx` | + +This skill reads **on-chain state** and runs **ops cadences**. It does not replace source-code audits or token setup guides. + +## Program IDs (mainnet) + +| Program | Address | +|---------|---------| +| SPL Token | `TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA` | +| Token-2022 | `TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb` | +| BPF Upgradeable Loader | `BPFLoaderUpgradeab1e11111111111111111111111` | +| Metaplex Token Metadata | `metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s` | + +## RPC read patterns + +```bash +# Mint (jsonParsed) +solana account --output json --url mainnet-beta + +# Program + upgrade authority (explorer often clearer for ProgramData) +solana program show --url mainnet-beta +``` + +Prefer Helius MCP (kit) for batch reads when available. + +## Snapshot files + +| File | Purpose | +|------|---------| +| `authority-baseline.json` | Drift detection reference | +| `authority-launch-report.yaml` | T-0 gate output | +| `authority-weekly-YYYY-Www.yaml` | Weekly review archive | + +Store in private repo `ops/authorities/` — pubkeys only. + +## Skill boundaries (kit) + +| Topic | Use instead | +|-------|-------------| +| Write Anchor / client code | solana-dev-skill | +| Create token / Token-2022 setup | token-engineer agent | +| Code audit / vuln scan | Trail of Bits, safe-solana-builder | +| Metaplex integration patterns | ext/metaplex | +| User tx failed in wallet | `/debug-user-tx` (not authority ops) | +| Treasury runway / payroll | Out of scope | +| Governance voting / DAO ops | Out of scope | + +## External links + +- [Solana AI Kit](https://github.com/solanabr/solana-ai-kit) +- [solana-game-skill](https://github.com/solanabr/solana-game-skill) (reference structure) +- [Squads](https://squads.so) — verify vault addresses on official UI +- [Solana explorers](https://explorer.solana.com) — cross-check RPC reads + +## Maintenance notes (maintainers) + +Refresh when: + +- Token-2022 extension set changes materially +- Squads v4 account layout changes (update multisig module only) +- Metaplex Core becomes default for new launches (extend metadata module) + +Quarterly review is sufficient under normal ecosystem churn. diff --git a/authority-surface-ops-skill/skill/upgrade-authority.md b/authority-surface-ops-skill/skill/upgrade-authority.md new file mode 100644 index 0000000..a112566 --- /dev/null +++ b/authority-surface-ops-skill/skill/upgrade-authority.md @@ -0,0 +1,65 @@ +# Upgrade Authority + +Verify whether a deployed program can be replaced and who controls upgrades. + +## Applies to + +- BPF Loader Upgradeable programs +- Not applicable to **immutable** (non-upgradeable) deployments + +## Read procedure + +1. Confirm program ID and cluster. +2. Fetch program account — note `programData` address. +3. Fetch ProgramData account — read **upgrade authority** field. + +```yaml +program_id:
+loader: bpf-upgradeable-v2 +program_data:
+upgrade_authority: + present: true | false + holder: # null = immutable (authority revoked) +slot_last_deploy: +``` + +4. If `upgrade_authority` is null → program is **immutable** (verify this matches team intent). + +## Severity rubric + +| State | Severity | blocks_launch | +|-------|----------|---------------| +| Upgrade authority on single hot wallet | **critical** | true | +| Upgrade authority on multisig without documented timelock | **high** | review | +| Upgrade authority revoked (immutable) but docs say "upgradeable" | medium | review | +| Upgrade authority = expected Squads vault | info | false | +| Unexpected upgrade slot activity in drift review | **critical** | escalate | + +## Launch-week expectations + +| Stage | Expected state | +|-------|----------------| +| Pre-audit | Upgradeable + multisig (for fixes) | +| Post-audit, pre-TVL | Document upgrade policy | +| Mature / high TVL | Many teams revoke (immutable) — explicit decision | + +## Drift signal + +ProgramData account size or authority field change without scheduled upgrade → treat as [incident-handoff.md](incident-handoff.md). + +## Output snippet + +```yaml +findings: + - id: F-upg-001 + severity: critical + surface: upgrade + observation: "Upgrade authority 5def... — single wallet, not Squads" + recommendation: "Transfer upgrade authority to multisig before accepting user funds" + blocks_launch: true +``` + +## Delegation + +- Writing upgrade txs / buffer deploy → solana-dev → programs-anchor.md +- Reviewing upgrade instruction handlers → security / audit skills diff --git a/authority-surface-ops-skill/skill/weekly-review.md b/authority-surface-ops-skill/skill/weekly-review.md new file mode 100644 index 0000000..0acbee0 --- /dev/null +++ b/authority-surface-ops-skill/skill/weekly-review.md @@ -0,0 +1,74 @@ +# Weekly Review Checklist + +~30-minute recurring authority ops cadence for live projects. + +## Prerequisites + +- Current baseline JSON ([authority-drift.md](authority-drift.md)) +- List of in-scope assets (mints, programs, multisigs) — changes require explicit add/remove + +## Weekly script (same order every week) + +### 1. Inventory confirm (5 min) + +- [ ] All mints still in scope +- [ ] All programs still in scope +- [ ] Multisig vault unchanged + +### 2. Surface re-read (15 min) + +For each asset: + +- [ ] Mint + freeze ([mint-freeze-authority.md](mint-freeze-authority.md)) +- [ ] Metadata ([metadata-authority.md](metadata-authority.md)) +- [ ] Upgrade ([upgrade-authority.md](upgrade-authority.md)) + +### 3. Drift diff (5 min) + +- [ ] Run [authority-drift.md](authority-drift.md) against baseline +- [ ] `critical` or `high` drift → [incident-handoff.md](incident-handoff.md) same day + +### 4. Pending multisig (5 min) + +- [ ] List open Squads proposals touching authorities +- [ ] Run [multisig-verification.md](multisig-verification.md) before any signatures this week + +### 5. Update baseline + +- [ ] If clean: update `captured_at` timestamp only +- [ ] If intentional authority change: new baseline + document reason in commit message + +## Weekly report template + +```yaml +weekly_review: + week_of: "2026-W25" + assets_reviewed: 4 + drift: + critical: 0 + high: 0 + pending_multisig: 1 + verdict: clean | investigate | incident + next_review: "2026-06-25" +``` + +## When to skip + +Never skip if: + +- TVL > 0 +- Launch was within last 30 days +- Any open incident + +## When to escalate frequency + +Move to **daily** surface read if: + +- Active launch campaign +- Known ecosystem exploit in similar protocol +- Team member with authority access departed + +## Delegation + +- Engineering sprints / feature work → solana-dev +- Full code audit schedule → audit skills (quarterly, separate calendar) diff --git a/authority-surface-ops-skill/validate.sh b/authority-surface-ops-skill/validate.sh new file mode 100755 index 0000000..fabeddb --- /dev/null +++ b/authority-surface-ops-skill/validate.sh @@ -0,0 +1,88 @@ +#!/usr/bin/env bash +# Validate skill structure, links, and agent/command frontmatter +set -euo pipefail + +ROOT="$(cd "$(dirname "$0")" && pwd)" +SKILL="${ROOT}/skill/SKILL.md" +PASS=0 +FAIL=0 + +check() { + if [[ "$2" -eq 0 ]]; then + echo "PASS: $1" + PASS=$((PASS + 1)) + else + echo "FAIL: $1" + FAIL=$((FAIL + 1)) + fi +} + +echo "Validating Authority Surface Ops Skill..." +echo "" + +[[ -f "$SKILL" ]]; check "SKILL.md exists" $? + +broken=0 +while IFS= read -r link; do + link="$(echo "$link" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')" + [[ -z "$link" ]] && continue + [[ "$link" == http* ]] && continue + target="${ROOT}/skill/${link}" + if [[ ! -f "$target" ]]; then + echo "FAIL: broken link in SKILL.md -> $link" + FAIL=$((FAIL + 1)) + broken=$((broken + 1)) + fi +done < <(grep -oE '\]\([^)]+\)' "$SKILL" | sed 's/\](//;s/)//' | grep '\.md$') + +[[ "$broken" -eq 0 ]] && check "SKILL.md local links resolve" 0 || true + +module_fail=0 +for f in "${ROOT}"/skill/*.md; do + [[ -f "$f" ]] || continue + [[ "$(basename "$f")" == "SKILL.md" ]] && continue + lines=$(wc -l < "$f") + if [[ "$lines" -lt 20 ]]; then + echo "FAIL: $(basename "$f") too short ($lines lines)" + module_fail=$((module_fail + 1)) + fi +done +[[ "$module_fail" -eq 0 ]]; check "skill modules meet minimum depth" $? + +AGENT="${ROOT}/agents/authority-ops-engineer.md" +if [[ -f "$AGENT" ]] && head -1 "$AGENT" | grep -q '^---'; then + fm=$(awk '/^---$/{c++;next} c==1{print; if(NR>30)exit}' "$AGENT") + echo "$fm" | grep -q '^name:' && check "agent has name" 0 || check "agent has name" 1 + echo "$fm" | grep -q '^description:' && check "agent has description" 0 || check "agent has description" 1 + echo "$fm" | grep -q '^model:' && check "agent has model" 0 || check "agent has model" 1 + grep -q '../skills/authority-surface-ops/' "$AGENT" && check "agent uses installed skill paths" 0 || check "agent uses installed skill paths" 1 +else + check "agent frontmatter" 1 +fi + +CMD="${ROOT}/commands/authority-surface-audit.md" +if [[ -f "$CMD" ]] && head -1 "$CMD" | grep -q '^---'; then + fm=$(awk '/^---$/{c++;next} c==1{print; if(NR>15)exit}' "$CMD") + echo "$fm" | grep -q '^description:' && check "command has description" 0 || check "command has description" 1 +else + check "command frontmatter" 1 +fi + +[[ -x "${ROOT}/install.sh" ]]; check "install.sh executable" $? +[[ -x "${ROOT}/scripts/check-mint-authorities.sh" ]]; check "check-mint-authorities.sh executable" $? +[[ -x "${ROOT}/scripts/check-program-upgrade.sh" ]]; check "check-program-upgrade.sh executable" $? +[[ -f "${ROOT}/CLAUDE.md" ]]; check "CLAUDE.md exists" $? +[[ -f "${ROOT}/.github/workflows/ci.yml" ]]; check "CI workflow exists" $? +[[ -f "${ROOT}/LICENSE" ]]; check "LICENSE exists" $? +[[ -f "${ROOT}/docs/KIT_INTEGRATION.md" ]]; check "KIT_INTEGRATION.md exists" $? + +for report in launch-go-ray.yaml launch-no-go-active-authorities.yaml drift-critical-mint.yaml upgrade-immutable-program.yaml weekly-review-clean.yaml; do + [[ -f "${ROOT}/examples/reports/${report}" ]] && check "example report ${report}" 0 || check "example report ${report}" 1 +done + +[[ -f "${ROOT}/examples/output/ray-mainnet-report.txt" ]]; check "live output ray-mainnet" $? +[[ -f "${ROOT}/examples/output/token-program-upgrade-report.txt" ]]; check "live output token-program-upgrade" $? + +echo "" +echo "Results: $PASS passed, $FAIL failed" +[[ "$FAIL" -eq 0 ]]