diff --git a/.cursor-plugin/marketplace.json b/.cursor-plugin/marketplace.json index 9455c0a..f50eebe 100644 --- a/.cursor-plugin/marketplace.json +++ b/.cursor-plugin/marketplace.json @@ -12,7 +12,7 @@ "name": "qring", "source": "cursor-plugin", "description": "Quantum keyring for AI agents — manage secrets, scan for leaks, rotate keys, and enforce policy directly from Cursor.", - "version": "0.10.1", + "version": "0.11.5", "keywords": [ "secrets", "keyring", @@ -22,7 +22,7 @@ "dotenv", "credential-management" ], - "logo": "https://raw.githubusercontent.com/I4cTime/quantum_ring/main/web/public/assets/logo.png" + "logo": "https://raw.githubusercontent.com/I4cTime/quantum_ring/main/assets/logo.png" } ] } diff --git a/.github/workflows/deploy-pages.yml b/.github/workflows/deploy-pages.yml deleted file mode 100644 index 11ad768..0000000 --- a/.github/workflows/deploy-pages.yml +++ /dev/null @@ -1,52 +0,0 @@ -# Build web/ Next.js static export and push to gh-pages branch. -# Triggers on pushes to main that touch web/ files, or on manual dispatch. - -name: Deploy Pages - -on: - push: - branches: [main] - paths: - - "web/**" - workflow_dispatch: - -permissions: - contents: write - -defaults: - run: - working-directory: web - -jobs: - deploy: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - uses: pnpm/action-setup@v4 - with: - version: latest - - - uses: actions/setup-node@v4 - with: - node-version: "22" - cache: pnpm - cache-dependency-path: web/pnpm-lock.yaml - - - name: Install dependencies - env: - # Required by @heroui-pro/react postinstall to download licensed - # bundle from the HeroUI CDN. Stored as a repo secret. - HEROUI_AUTH_TOKEN: ${{ secrets.HEROUI_AUTH_TOKEN }} - run: pnpm install --frozen-lockfile - - - name: Build - run: pnpm run build - - - name: Deploy to gh-pages - uses: peaceiris/actions-gh-pages@v4 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: web/out - force_orphan: true - cname: qring.i4c.studio diff --git a/.github/workflows/nextjs.yml b/.github/workflows/nextjs.yml deleted file mode 100644 index 357bfa0..0000000 --- a/.github/workflows/nextjs.yml +++ /dev/null @@ -1,53 +0,0 @@ -# Next.js CI — runs only when files under web/ change (add your app at ./web). -# To use the repo root instead, remove defaults.run.working-directory and adjust cache paths. - -name: Next.js - -on: - push: - branches: [develop] - paths: - - "web/**" - pull_request: - branches: [develop, main] - paths: - - "web/**" - -permissions: - contents: read - -defaults: - run: - working-directory: web - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - uses: pnpm/action-setup@v4 - with: - version: latest - - - uses: actions/setup-node@v4 - with: - node-version: "24" - cache: pnpm - cache-dependency-path: web/pnpm-lock.yaml - - - name: Install dependencies - env: - # Required by @heroui-pro/react postinstall to download licensed - # bundle from the HeroUI CDN. Stored as a repo secret. - HEROUI_AUTH_TOKEN: ${{ secrets.HEROUI_AUTH_TOKEN }} - run: pnpm install --frozen-lockfile - - - name: Lint - run: pnpm run --if-present lint - - - name: Build - run: pnpm run build - - - name: Test - run: pnpm run --if-present test diff --git a/.gitignore b/.gitignore index 09662bf..59fa3fc 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,19 @@ package-lock.json !cursor-plugin/commands/*secret*.md !cursor-plugin/commands/*token*.md !.cursor/rules/secret-*.mdc - +!claude-code-plugin/.claude/skills/secret-*/ +!claude-code-plugin/.claude/skills/secret-*/** +!claude-code-plugin/.claude/skills/exec-with-secrets/ +!claude-code-plugin/.claude/skills/exec-with-secrets/** +!claude-code-plugin/.claude/agents/secret-*.md +!claude-code-plugin/.claude/commands/*secret*.md +!claude-code-plugin/.claude/commands/*token*.md +!kiro-plugin/steering/qring-secret-*.md +!kiro-plugin/steering/qring-*-secrets.md +!kiro-plugin/steering/qring-exec-with-secrets.md +marketing/ # Local-only publishing checklist (not pushed to GitHub) docs/publishing-log.md + +# Local-only GTM / campaign drafts (see marketing/README.md) +local/ diff --git a/CHANGELOG.md b/CHANGELOG.md index e15578f..f03d84a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,22 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +## [0.11.5] — 2026-04-27 + +### Added +- **Kiro Power pack** (`kiro-plugin/`) — steering files, hook templates, and `mcp.json` for [Kiro](https://kiro.dev); `pnpm run plugin:sync:kiro` copies into `~/.kiro` or a project `.kiro` path. +- **Claude Code plugin** (`claude-code-plugin/`) — `CLAUDE.md`, project `.mcp.json`, agents, slash commands, skills, and hooks; `pnpm run plugin:sync:claude` for project install or `--user` for `~/.claude`. + +### Removed +- **In-repo marketing site (`web/`)** — the embedded Next.js app was removed from this repository; public docs and marketing are served from **https://qring.i4c.studio**. Removed GitHub Actions workflows `deploy-pages.yml` and `nextjs.yml`, and the `web:extract-repo` script. + +### Changed +- **`package.json` `homepage`** — now `https://qring.i4c.studio`. +- **Cursor plugin / marketplace metadata** — logo URL points at repo-root `assets/logo.png` on GitHub raw (replacing deleted `web/public/` paths). +- **README** — new “Editor plugins” section for Cursor, Kiro, and Claude Code, including sync commands and contributor notes. +- **`.gitignore`** — ignore `marketing/` and `local/` for local-only drafts. +- **MCP tool descriptions** — clearer operator guidance for `detect_anomalies`, `health_check`, `remove_hook`, `set_secret`, `delete_secret`, `entangle_secrets`, `disentangle_secrets`, and `agent_scan` (read-only versus mutating behavior and related tools). + ## [0.11.0] — 2026-04-25 ### Changed diff --git a/README.md b/README.md index 06848c3..c874332 100644 --- a/README.md +++ b/README.md @@ -811,21 +811,66 @@ Add to `~/.claude/claude_desktop_config.json`: } ``` -## Cursor Plugin +## Editor Plugins + +The q-ring repo ships three first-party editor packs — each one adds rules/steering, agents, commands, skills, hooks, and the MCP connector to its host editor. + +| Plugin | Editor | Highlights | +|--------|--------|-----------| +| [`cursor-plugin/`](cursor-plugin/README.md) | [Cursor](https://cursor.com) | 3 rules, 5 skills, 2 agents, 8 slash commands, 3 hooks, MCP autoconnect | +| [`kiro-plugin/`](kiro-plugin/README.md) | [Kiro](https://kiro.dev) | Official [Power](https://kiro.dev/docs/powers/create/) layout: `POWER.md`, root `mcp.json`, `steering/`, `hooks/`; or flatten with `plugin:sync:kiro` | +| [`claude-code-plugin/`](claude-code-plugin/README.md) | [Claude Code](https://docs.claude.com/en/docs/claude-code/overview) | `CLAUDE.md` memory, project `.mcp.json`, 2 subagents, 8 slash commands, 5 skills, 3 hook scripts | + +### Cursor Plugin The **q-ring Cursor Plugin** brings quantum secret management directly into your IDE with rules, skills, agents, commands, hooks, and a built-in MCP connector. | Component | What it does | |-----------|-------------| | **3 Rules** | Always-on guidance: never hardcode secrets, use q-ring for all ops, warn about `.env` files | -| **4 Skills** | Auto-triggered by context: secret management, scanning, rotation, project onboarding | +| **5 Skills** | Auto-triggered by context: secret management, scanning, rotation, project onboarding, exec-with-secrets | | **2 Agents** | `security-auditor` (proactive monitoring) and `secret-ops` (day-to-day assistant) | -| **5 Commands** | `/qring:scan-secrets`, `/qring:health-check`, `/qring:rotate-expired`, `/qring:setup-project`, `/qring:teleport-secrets` | -| **2 Hooks** | `afterFileEdit` (lint scan), `sessionStart` (project context) | +| **8 Commands** | `/qring:scan-secrets`, `/qring:health-check`, `/qring:rotate-expired`, `/qring:setup-project`, `/qring:teleport-secrets`, `/qring:dashboard`, `/qring:exec-safe`, `/qring:analyze` | +| **3 Hooks** | `afterFileEdit` (lint scan), `sessionStart` (project context), `beforeShellExecution` (`.env` guard) | | **MCP Connector** | Auto-connects to `qring-mcp` via stdio — all 44 tools available | Install from the Cursor marketplace or see [`cursor-plugin/README.md`](cursor-plugin/README.md) for manual setup. +### Kiro Plugin (Power) + +The [`kiro-plugin/`](kiro-plugin/) directory is a Kiro **Power** per [Create powers](https://kiro.dev/docs/powers/create/): `POWER.md` (metadata, onboarding, steering map), root [`mcp.json`](kiro-plugin/mcp.json) (MCP server must match the server name referenced in the power), and [`steering/`](kiro-plugin/steering/) for workflows. Install from Kiro → **Powers** → **Add power from Local Path** and select `kiro-plugin`, or publish the folder on GitHub and use **Add power from GitHub**. + +Always-on steering blocks hardcoded secrets and routes everything through q-ring; `manual` steering files act as agent personas (`#qring-secret-ops`, `#qring-security-auditor`), skill packs, and slash-style commands (`#qring-cmd-scan-secrets`, etc.). Optional hooks live in `hooks/` for copy into `.kiro/hooks/`. + +```bash +# Alternative: flatten into ~/.kiro (settings + steering + hooks) +pnpm run plugin:sync:kiro + +# Or scope to a single project +pnpm run plugin:sync:kiro -- /path/to/your/project/.kiro +``` + +See [`kiro-plugin/README.md`](kiro-plugin/README.md) for the full breakdown. + +### Claude Code Plugin + +For [Claude Code](https://docs.claude.com/en/docs/claude-code/overview), q-ring ships a `CLAUDE.md` memory file, a project-scoped `.mcp.json`, two [subagents](https://docs.claude.com/en/docs/claude-code/sub-agents) (`secret-ops`, `security-auditor`), eight [slash commands](https://docs.claude.com/en/docs/claude-code/slash-commands) (`/qring-scan-secrets`, `/qring-health-check`, …), five [skills](https://docs.claude.com/en/docs/claude-code/skills), and three [hooks](https://docs.claude.com/en/docs/claude-code/hooks) (post-edit lint reminder, pre-Bash `.env` guard, session-start context primer). + +```bash +# Install into the current project ($PWD) +pnpm run plugin:sync:claude + +# Install agents/commands/skills/hooks at user scope (~/.claude) +pnpm run plugin:sync:claude -- --user + +# Or target a specific project +pnpm run plugin:sync:claude -- /path/to/your/project +``` + +Existing `CLAUDE.md`, `.mcp.json`, or `.claude/settings.json` files are never silently overwritten — the script writes a `.qring-template` next to them so you can merge by hand. Pass `--force` to overwrite. + +See [`claude-code-plugin/README.md`](claude-code-plugin/README.md) for the full breakdown. + ## Architecture ``` @@ -900,7 +945,11 @@ Optional per-project configuration: - Run **`pnpm run lint`**, **`pnpm run typecheck`**, and **`pnpm run test:ci`** before opening a PR. - Tests or sandboxes can point the audit log elsewhere with **`QRING_AUDIT_DIR`** (directory is created if missing); default is `~/.config/q-ring/audit.jsonl`. - Optional local pre-commit: **`qring hook:install`** (uses this package’s `precommit` hook when `qring` is on your `PATH`). -- After changing the Cursor plugin under **`cursor-plugin/`**, run **`pnpm run plugin:sync`** to copy it to `~/.cursor/plugins/local/my-plugin` (or pass a custom path). See also [docs/cli-mcp-parity.md](docs/cli-mcp-parity.md). +- After changing one of the editor plugins: + - **Cursor:** `pnpm run plugin:sync` copies `cursor-plugin/` to `~/.cursor/plugins/local/my-plugin` (or pass a custom path). + - **Kiro:** `pnpm run plugin:sync:kiro` copies `kiro-plugin/mcp.json` → `~/.kiro/settings/mcp.json`, plus `steering/` and `hooks/` (or pass a project `.kiro` path). Prefer adding `kiro-plugin/` as a [Power](https://kiro.dev/docs/powers/create/) from the Powers panel instead. + - **Claude Code:** `pnpm run plugin:sync:claude` copies `claude-code-plugin/` into the current directory (or pass a project path; add `--user` to install at `~/.claude/`). +- See also [docs/cli-mcp-parity.md](docs/cli-mcp-parity.md). ## 📜 License diff --git a/SECURITY.md b/SECURITY.md index 136f629..b2fd56d 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -4,8 +4,8 @@ | Version | Supported | |---------|-----------| -| 0.10.x | Yes | -| < 0.10 | No | +| 0.11.x | Yes | +| < 0.11 | No | ## Reporting a Vulnerability diff --git a/claude-code-plugin/.claude/agents/secret-ops.md b/claude-code-plugin/.claude/agents/secret-ops.md new file mode 100644 index 0000000..5c474de --- /dev/null +++ b/claude-code-plugin/.claude/agents/secret-ops.md @@ -0,0 +1,51 @@ +--- +name: secret-ops +description: Day-to-day secret operations assistant. Use proactively when the user wants to store, retrieve, generate, share, organize, or transfer secrets — API keys, tokens, credentials, .env values. Handles superposition (multi-environment), entanglement (linked rotation), tunnels (ephemeral), and teleport (encrypted bundles). +tools: mcp__q-ring__get_secret, mcp__q-ring__set_secret, mcp__q-ring__delete_secret, mcp__q-ring__has_secret, mcp__q-ring__list_secrets, mcp__q-ring__inspect_secret, mcp__q-ring__generate_secret, mcp__q-ring__entangle_secrets, mcp__q-ring__disentangle_secrets, mcp__q-ring__tunnel_create, mcp__q-ring__tunnel_read, mcp__q-ring__tunnel_list, mcp__q-ring__tunnel_destroy, mcp__q-ring__teleport_pack, mcp__q-ring__teleport_unpack, mcp__q-ring__detect_environment, mcp__q-ring__get_project_context, mcp__q-ring__agent_remember, mcp__q-ring__agent_recall, mcp__q-ring__agent_forget, mcp__q-ring__import_dotenv, mcp__q-ring__export_secrets +--- + +# Secret Ops + +You are a hands-on secret operations assistant for q-ring. You help users manage their secrets through natural conversation. + +## Capabilities + +You have access to all q-ring MCP tools, with emphasis on: + +**Core CRUD** +- `get_secret`, `set_secret`, `delete_secret`, `has_secret`, `list_secrets` +- `inspect_secret` — view metadata without exposing values +- `generate_secret` — create high-entropy secrets in any format (hex, base64, uuid, api-key, token, password) + +**Ephemeral sharing** +- `tunnel_create` — create memory-only secrets with TTL and max-reads +- `tunnel_read`, `tunnel_list`, `tunnel_destroy` + +**Cross-machine transfer** +- `teleport_pack` — encrypt secrets into a portable bundle +- `teleport_unpack` — decrypt and import a bundle + +**Organization** +- `entangle_secrets` / `disentangle_secrets` — link secrets for coordinated rotation +- `agent_remember` / `agent_recall` / `agent_forget` — persist decisions across sessions + +**Environment** +- `detect_environment` — detect dev/staging/prod context +- `get_project_context` — understand the project's secret landscape + +## Behavior + +1. **Be conversational.** Help users think through what they need. Ask clarifying questions about scope (global vs project), environment, and TTL. +2. **Remember context.** Use `agent_remember` to store decisions like "this project uses OpenAI and Stripe" or "DB credentials rotate monthly". Use `agent_recall` to check past context before asking redundant questions. +3. **Suggest best practices:** + - Generate secrets with `generate_secret` instead of letting users invent them + - Add descriptions and tags for organization + - Set TTL for credentials that expire + - Use tunnels for one-time sharing instead of pasting values + - Use teleport for moving secrets between machines +4. **Be scope-aware.** When storing or retrieving secrets, consider whether the user needs global scope (shared across projects) or project scope (specific to the current workspace). +5. **Explain what happened.** After operations, confirm what was done: "Stored API_KEY in global scope with tag 'openai' and 90-day TTL." + +## Tone + +Be helpful and efficient. Explain q-ring concepts (superposition, entanglement, tunneling) in plain terms when users encounter them for the first time. diff --git a/claude-code-plugin/.claude/agents/security-auditor.md b/claude-code-plugin/.claude/agents/security-auditor.md new file mode 100644 index 0000000..d273cc1 --- /dev/null +++ b/claude-code-plugin/.claude/agents/security-auditor.md @@ -0,0 +1,42 @@ +--- +name: security-auditor +description: Proactive security monitoring agent for q-ring. Use proactively when the user mentions security audit, anomaly detection, audit log integrity, governance policy, or wants a periodic check on the project's secret posture. Verifies the tamper-evident audit chain, surfaces stale or expired credentials, scans for hardcoded leaks, and reports policy violations. +tools: mcp__q-ring__health_check, mcp__q-ring__audit_log, mcp__q-ring__verify_audit_chain, mcp__q-ring__detect_anomalies, mcp__q-ring__scan_codebase_for_secrets, mcp__q-ring__check_policy, mcp__q-ring__get_policy_summary, mcp__q-ring__export_audit, mcp__q-ring__list_secrets, mcp__q-ring__inspect_secret, mcp__q-ring__get_project_context, mcp__q-ring__analyze_secrets +--- + +# Security Auditor + +You are a security-focused agent for q-ring. Your job is to proactively monitor the health and integrity of the project's secret management. + +## Capabilities + +You have access to these q-ring MCP tools: + +- `health_check` — assess decay, staleness, and anomalies across all secrets +- `audit_log` — query the tamper-evident audit trail (filter by key, action, source, time) +- `verify_audit_chain` — verify the SHA-256 hash chain has not been tampered with +- `detect_anomalies` — flag burst reads, unusual-hour access, new sources, and tampering +- `scan_codebase_for_secrets` — scan the project for hardcoded credentials +- `check_policy` — verify an action is allowed by governance policy +- `get_policy_summary` — show the full policy configuration +- `export_audit` — export audit events as JSONL, JSON, or CSV + +## Behavior + +1. **Start with a health check.** Call `health_check` to get the overall status. Report expired, stale, and healthy counts. +2. **Verify audit integrity.** Call `verify_audit_chain` to confirm the hash chain is intact. If broken, report the break point and affected event. +3. **Detect anomalies.** Call `detect_anomalies` to find suspicious patterns: + - **Burst reads** — many reads of the same key in a short window + - **Unusual-hour access** — reads outside normal working hours + - **New source** — access from a previously unseen source + - **Tampering** — audit entries with invalid hashes +4. **Scan for leaks.** Call `scan_codebase_for_secrets` on the project directory and report any hardcoded credentials found. +5. **Check governance.** If a `.q-ring.json` policy exists, call `get_policy_summary` and verify that denied tools, keys, and tags are properly configured. +6. **Generate a report.** Summarize findings with counts and severity levels: + - **Critical:** tampered audit chain, hardcoded secrets, expired credentials + - **Warning:** stale secrets, anomalous access patterns + - **Info:** healthy secret counts, policy status + +## Tone + +Be direct and factual. Present findings as a structured report. Recommend specific remediation actions for each issue found. diff --git a/claude-code-plugin/.claude/commands/qring-analyze.md b/claude-code-plugin/.claude/commands/qring-analyze.md new file mode 100644 index 0000000..56a34b9 --- /dev/null +++ b/claude-code-plugin/.claude/commands/qring-analyze.md @@ -0,0 +1,13 @@ +--- +description: Run q-ring usage / optimization analysis — heavy keys, unused entries, decay risks. +allowed-tools: mcp__q-ring__analyze_secrets, mcp__q-ring__list_secrets +--- + +# /qring-analyze + +Run q-ring's secret usage and optimization analysis. Use when the user asks how secrets are used, which keys are stale, or for cleanup suggestions. + +## Workflow + +1. Call MCP tool `analyze_secrets` with the relevant `projectPath` / scope options. +2. Summarize the JSON output: heavy keys, unused entries, decay risks, scope-optimization hints, and concrete next steps the user can take (e.g. delete unused keys, set TTL on keys without decay tracking, rotate stale credentials). diff --git a/claude-code-plugin/.claude/commands/qring-dashboard.md b/claude-code-plugin/.claude/commands/qring-dashboard.md new file mode 100644 index 0000000..d7accf4 --- /dev/null +++ b/claude-code-plugin/.claude/commands/qring-dashboard.md @@ -0,0 +1,32 @@ +--- +description: Start the q-ring local status dashboard (SSE + browser UI) for live secret/health monitoring. +allowed-tools: mcp__q-ring__status_dashboard +--- + +# /qring-dashboard + +Start the q-ring local status dashboard. Use when the user wants a live view of secret health, manifest gaps, policy posture, approvals, hooks, and audit traffic without exposing secret values. + +## Workflow + +1. Call MCP tool `status_dashboard`. +2. Report the returned `http://127.0.0.1:…` URL so the user can open it in a browser (local only — bound to loopback). + +If the dashboard is already running, the tool reports the existing URL instead of starting a second listener. + +## What the page shows + +- **KPI strip** — total secrets, detected env, protected count, active approvals, hooks, 24h reads/writes, denied actions, and live anomaly count. +- **Health summary** — donut of healthy / stale / expired / no-decay secrets with per-scope breakdown. +- **Environment** — wavefunction collapse details (env, source, branch). +- **Manifest** — declared / required / missing / expired / stale keys from `.q-ring.json`. +- **Policy** — MCP / exec / secret policy presence with allow-deny / approval / rotation counts. +- **Secrets table** — sortable, searchable view of every secret with quick chips for `expired`, `stale`, `protected`. +- **Quantum cards** — decay timers, superposition states, entanglement pairs, active tunnels. +- **Approvals & hooks** — live grants and registered hooks with tamper / expiry state and match summaries. +- **Agent memory** — count of encrypted memory keys. +- **Anomaly alerts + audit feed** — filterable by action and source with free-text search. + +## Important + +The dashboard never renders secret **values** — only metadata. It is safe to share a screenshot for debugging, but the bound URL stays on `127.0.0.1` and should not be exposed beyond the local machine. diff --git a/claude-code-plugin/.claude/commands/qring-exec-safe.md b/claude-code-plugin/.claude/commands/qring-exec-safe.md new file mode 100644 index 0000000..738a21a --- /dev/null +++ b/claude-code-plugin/.claude/commands/qring-exec-safe.md @@ -0,0 +1,23 @@ +--- +description: Run a shell command with q-ring-injected secrets and stdout/stderr redaction. +argument-hint: " [args...]" +allowed-tools: mcp__q-ring__exec_with_secrets, mcp__q-ring__check_policy, mcp__q-ring__get_policy_summary +--- + +# /qring-exec-safe + +Run a shell command with q-ring secrets injected into the environment, and stdout/stderr automatically redacted of any known secret values. + +The command and args are taken from `$ARGUMENTS`. + +## Workflow + +1. Confirm `get_policy_summary` / `check_policy` allows `exec_with_secrets` for this project. +2. Call `exec_with_secrets` with explicit argv (array), the workspace as `projectPath`, and minimal secret scope (use `tags` or `keys` to restrict which secrets are loaded). +3. Present stdout/stderr safely; never repeat suspected secret substrings in follow-up messages. + +## Safety + +- Never log raw command output to public channels without reviewing redaction limits. +- If unsure which secrets the command needs, ask the user — do not load every secret into the environment by default. +- Consider running with `profile: "restricted"` for one-off commands. diff --git a/claude-code-plugin/.claude/commands/qring-health-check.md b/claude-code-plugin/.claude/commands/qring-health-check.md new file mode 100644 index 0000000..0e02c8f --- /dev/null +++ b/claude-code-plugin/.claude/commands/qring-health-check.md @@ -0,0 +1,26 @@ +--- +description: Run a comprehensive q-ring health check — decay, anomalies, and audit chain integrity. +allowed-tools: mcp__q-ring__health_check, mcp__q-ring__detect_anomalies, mcp__q-ring__verify_audit_chain, mcp__q-ring__list_secrets +--- + +# /qring-health-check + +Run a full health assessment of all secrets managed by q-ring. + +## Workflow + +1. Call `health_check` to assess all secrets: + - Count healthy, stale (> 75% lifetime), and expired secrets + - Note any secrets without decay tracking +2. Call `detect_anomalies` to check for suspicious access patterns: + - Burst reads on a single key + - Access at unusual hours + - Access from new/unknown sources +3. Call `verify_audit_chain` to confirm the audit log has not been tampered with: + - Report total events and valid count + - If broken, show the break point +4. Present a summary report: + - Secrets: X healthy, Y stale, Z expired + - Anomalies: count and type + - Audit chain: intact or broken at event N + - Recommendations for any issues found diff --git a/claude-code-plugin/.claude/commands/qring-rotate-expired.md b/claude-code-plugin/.claude/commands/qring-rotate-expired.md new file mode 100644 index 0000000..3ae6b89 --- /dev/null +++ b/claude-code-plugin/.claude/commands/qring-rotate-expired.md @@ -0,0 +1,22 @@ +--- +description: Find expired and stale secrets and attempt automatic rotation via their providers. +allowed-tools: mcp__q-ring__health_check, mcp__q-ring__validate_secret, mcp__q-ring__rotate_secret, mcp__q-ring__list_secrets, mcp__q-ring__inspect_secret +--- + +# /qring-rotate-expired + +Find all expired or stale secrets and attempt to rotate them. + +## Workflow + +1. Call `health_check` to identify expired and stale secrets. +2. If no expired or stale secrets exist, report that everything is healthy and stop. +3. For each expired secret: + 1. Call `validate_secret` to confirm it is actually invalid. + 2. Call `rotate_secret` to attempt provider-native rotation. + 3. Report the result: rotated (with provider name) or failed (with reason). +4. For stale secrets (> 75% lifetime), list them as warnings with remaining time. +5. Present a summary: + - **Rotated:** N secrets successfully refreshed + - **Failed:** N secrets could not be rotated (manual intervention needed) + - **Stale:** N secrets approaching expiry diff --git a/claude-code-plugin/.claude/commands/qring-scan-secrets.md b/claude-code-plugin/.claude/commands/qring-scan-secrets.md new file mode 100644 index 0000000..31c50ee --- /dev/null +++ b/claude-code-plugin/.claude/commands/qring-scan-secrets.md @@ -0,0 +1,22 @@ +--- +description: Scan the workspace for hardcoded secrets, then offer to auto-fix them with q-ring. +argument-hint: "[path]" +allowed-tools: mcp__q-ring__scan_codebase_for_secrets, mcp__q-ring__lint_files, mcp__q-ring__list_secrets +--- + +# /qring-scan-secrets + +Scan the current workspace (or `$1` if provided) for hardcoded secrets, API keys, and credentials. + +## Workflow + +1. Call `scan_codebase_for_secrets` with the target directory (`$1` if provided, otherwise the workspace root). +2. If no secrets are found, report that the codebase is clean and stop. +3. If secrets are found, present them grouped by file: + - Show file path, line number, variable name, and entropy score + - Highlight high-entropy matches (> 4.0) as most likely real +4. Ask the user if they want to auto-fix: + - On yes, call `lint_files` with the affected files and `fix: true` + - This replaces hardcoded values with `process.env.KEY` references and stores the values in q-ring + - Report how many secrets were migrated +5. After fixing, re-run `scan_codebase_for_secrets` to confirm cleanup is complete. diff --git a/claude-code-plugin/.claude/commands/qring-setup-project.md b/claude-code-plugin/.claude/commands/qring-setup-project.md new file mode 100644 index 0000000..ce3add9 --- /dev/null +++ b/claude-code-plugin/.claude/commands/qring-setup-project.md @@ -0,0 +1,32 @@ +--- +description: Initialize q-ring for the current project — detect environment, create manifest, import .env, set up hooks. +allowed-tools: mcp__q-ring__detect_environment, mcp__q-ring__check_project, mcp__q-ring__import_dotenv, mcp__q-ring__env_generate, mcp__q-ring__register_hook, mcp__q-ring__get_project_context, mcp__q-ring__list_hooks, Read, Write, Edit +--- + +# /qring-setup-project + +Initialize q-ring for the current project with a manifest, environment detection, and secret import. + +## Workflow + +1. Call `detect_environment` to determine the current environment context (dev, staging, prod). +2. Check whether a `.q-ring.json` manifest already exists: + - If yes, call `check_project` to validate it and report missing or expired secrets. + - If no, guide the user through creating one. +3. Create a `.q-ring.json` manifest with: + - `env` and `defaultEnv` set to the detected environment + - `branchMap` mapping git branches to environments + - `secrets` declaring required credentials with descriptions and providers + - Optional `policy` section for governance +4. Check for existing `.env` files: + - If found, offer to import via `import_dotenv` with `skipExisting: true`. + - Verify `.env` is in `.gitignore`. +5. Call `env_generate` to produce a `.env` from the manifest. +6. Offer to register hooks via `register_hook`: + - Shell hooks for restarting services on credential changes + - HTTP hooks for deployment notifications +7. Summarize what was set up: + - Manifest location and declared secrets + - Imported secrets count + - Registered hooks + - Detected environment diff --git a/claude-code-plugin/.claude/commands/qring-teleport-secrets.md b/claude-code-plugin/.claude/commands/qring-teleport-secrets.md new file mode 100644 index 0000000..a8c30fd --- /dev/null +++ b/claude-code-plugin/.claude/commands/qring-teleport-secrets.md @@ -0,0 +1,34 @@ +--- +description: Pack secrets into an encrypted bundle or unpack a received bundle for cross-machine transfer. +argument-hint: "[pack|unpack]" +allowed-tools: mcp__q-ring__teleport_pack, mcp__q-ring__teleport_unpack, mcp__q-ring__list_secrets +--- + +# /qring-teleport-secrets + +Securely transfer secrets between machines using AES-256-GCM encrypted bundles. + +If `$1` is `pack` or `unpack`, skip the prompt and proceed directly. Otherwise ask the user which mode they want. + +## Pack (send secrets) + +1. Call `list_secrets` to show available secrets. +2. Ask the user which keys to include (or use tag-based selection). +3. Ask for a passphrase for encryption. +4. Call `teleport_pack` with the selected keys and passphrase. +5. Present the encrypted bundle string to the user for transfer (clipboard, secure channel, etc.). +6. Remind the user to share the passphrase through a separate channel. + +## Unpack (receive secrets) + +1. Ask the user to paste the encrypted bundle string. +2. Ask for the passphrase used during packing. +3. Call `teleport_unpack` with the bundle and passphrase. +4. Report the imported secrets: count, names, and scopes. +5. Offer to verify the imports with `list_secrets`. + +## Security notes + +- The bundle is AES-256-GCM encrypted — safe to transfer over untrusted channels. +- Always share the passphrase through a separate, secure channel (different from the bundle). +- Bundles are one-time use by convention — re-pack for additional transfers. diff --git a/claude-code-plugin/.claude/hooks/scripts/qring-post-edit-lint-hint.sh b/claude-code-plugin/.claude/hooks/scripts/qring-post-edit-lint-hint.sh new file mode 100755 index 0000000..3a951b3 --- /dev/null +++ b/claude-code-plugin/.claude/hooks/scripts/qring-post-edit-lint-hint.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +# q-ring · PostToolUse hook (Write/Edit/MultiEdit) +# +# Reads the Claude Code hook payload from stdin, extracts the edited file path +# (tool_input.file_path), and emits a non-blocking JSON instruction telling the +# agent to lint that file with the q-ring `lint_files` MCP tool. +# +# It never blocks the edit: even when q-ring or jq is missing, the hook exits 0 +# and prints nothing. + +set -u + +if ! command -v jq >/dev/null 2>&1; then + exit 0 +fi + +payload="$(cat 2>/dev/null || true)" +if [ -z "${payload}" ]; then + exit 0 +fi + +file_path="$(printf '%s' "${payload}" | jq -r '.tool_input.file_path // empty' 2>/dev/null)" +if [ -z "${file_path}" ] || [ "${file_path}" = "null" ]; then + exit 0 +fi + +case "${file_path}" in + *node_modules/*|*.git/*|*dist/*|*build/*|*coverage/*|*/.next/*|*/.venv/*|*/__pycache__/*) + exit 0 ;; + *.lock|*.lockb|*.pyc|*.png|*.jpg|*.jpeg|*.gif|*.webp|*.ico|*.svg|*.pdf|*.zip|*.tgz|*.tar|*.gz|*.mp3|*.mp4|*.mov|*.wav|*.bin|*.exe|*.dll|*.so|*.dylib) + exit 0 ;; +esac + +reason="The agent edited ${file_path}. Call the q-ring MCP tool \`lint_files\` for this single path. If hardcoded secrets are reported, summarize them concisely and ask whether to call \`lint_files\` again with \`fix: true\` to migrate the values into q-ring (replacing literal values with \`process.env.KEY\` style references)." + +jq -nc --arg r "${reason}" '{ + hookSpecificOutput: { + hookEventName: "PostToolUse", + additionalContext: $r + } +}' diff --git a/claude-code-plugin/.claude/hooks/scripts/qring-pre-bash-env-guard.sh b/claude-code-plugin/.claude/hooks/scripts/qring-pre-bash-env-guard.sh new file mode 100755 index 0000000..7c36b6a --- /dev/null +++ b/claude-code-plugin/.claude/hooks/scripts/qring-pre-bash-env-guard.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash +# q-ring · PreToolUse hook (Bash) +# +# Inspects the proposed shell command. If the command would print, stage, or +# commit a `.env` / `.env.*` file — or contains a credential-shaped literal — +# emit a permissionDecision=ask payload so the user is prompted to confirm. +# +# This hook never silently blocks; the worst it does is prompt for explicit +# approval. Required tools: jq. + +set -u + +if ! command -v jq >/dev/null 2>&1; then + exit 0 +fi + +payload="$(cat 2>/dev/null || true)" +if [ -z "${payload}" ]; then + exit 0 +fi + +cmd="$(printf '%s' "${payload}" | jq -r '.tool_input.command // empty' 2>/dev/null)" +if [ -z "${cmd}" ] || [ "${cmd}" = "null" ]; then + exit 0 +fi + +reason="" + +if echo "${cmd}" | grep -Eq '(^|[[:space:]])(cat|less|more|head|tail|bat)[[:space:]].*(\.env\b|\.env\.[A-Za-z0-9_.-]+)'; then + reason="The command would print the contents of a .env file. Secrets in .env should be migrated into q-ring with the \`import_dotenv\` MCP tool first; printing the file leaks them into terminal history and agent transcripts." +fi + +if [ -z "${reason}" ] && echo "${cmd}" | grep -Eq 'git[[:space:]]+(add|commit|push).*\.env(\b|\.[A-Za-z0-9_.-]+)'; then + reason="The command would stage, commit, or push a .env file. Verify .env* is in .gitignore and migrate the secrets into q-ring with \`import_dotenv\` before continuing." +fi + +if [ -z "${reason}" ] && echo "${cmd}" | grep -Eq '(sk-[A-Za-z0-9_-]{20,}|sk_(live|test)_[A-Za-z0-9]{20,}|ghp_[A-Za-z0-9]{30,}|AKIA[0-9A-Z]{16})'; then + reason="The command appears to contain a credential-shaped literal (looks like an OpenAI/Stripe/GitHub/AWS key). Run it via the \`exec_with_secrets\` MCP tool (or the \`/qring-exec-safe\` slash command) so the value comes from q-ring and stdout/stderr are redacted, instead of pasting it into shell history." +fi + +if [ -n "${reason}" ]; then + jq -nc --arg r "${reason}" '{ + hookSpecificOutput: { + hookEventName: "PreToolUse", + permissionDecision: "ask", + permissionDecisionReason: $r + } + }' +fi diff --git a/claude-code-plugin/.claude/hooks/scripts/qring-session-start.sh b/claude-code-plugin/.claude/hooks/scripts/qring-session-start.sh new file mode 100755 index 0000000..34c1004 --- /dev/null +++ b/claude-code-plugin/.claude/hooks/scripts/qring-session-start.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +# q-ring · SessionStart hook +# +# When a Claude Code session starts in this project, inject a one-line note +# telling the agent to call `get_project_context` if a `.q-ring.json` manifest +# is detected in the workspace. +# +# Always exits 0; never blocks the session. + +set -u + +if ! command -v jq >/dev/null 2>&1; then + exit 0 +fi + +dir="${CLAUDE_PROJECT_DIR:-${PWD}}" + +note="q-ring is wired into this project (see CLAUDE.md and .mcp.json). At the start of any secret-related task, call the \`get_project_context\` MCP tool for an up-to-date redacted view of secrets, environment, manifest, and policy. Available slash commands: /qring-scan-secrets, /qring-health-check, /qring-rotate-expired, /qring-setup-project, /qring-teleport-secrets, /qring-dashboard, /qring-exec-safe, /qring-analyze." + +if [ -f "${dir}/.q-ring.json" ]; then + note="${note}\n\nDetected \`.q-ring.json\` in the project root — the agent should call \`check_project\` to verify required secrets are present, and surface anything missing/expired/stale." +fi + +jq -nc --arg n "$(printf %b "${note}")" '{ + hookSpecificOutput: { + hookEventName: "SessionStart", + additionalContext: $n + } +}' diff --git a/claude-code-plugin/.claude/settings.json b/claude-code-plugin/.claude/settings.json new file mode 100644 index 0000000..7264e2c --- /dev/null +++ b/claude-code-plugin/.claude/settings.json @@ -0,0 +1,37 @@ +{ + "$schema": "https://json.schemastore.org/claude-code-settings.json", + "hooks": { + "PostToolUse": [ + { + "matcher": "Write|Edit|MultiEdit", + "hooks": [ + { + "type": "command", + "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/scripts/qring-post-edit-lint-hint.sh" + } + ] + } + ], + "PreToolUse": [ + { + "matcher": "Bash", + "hooks": [ + { + "type": "command", + "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/scripts/qring-pre-bash-env-guard.sh" + } + ] + } + ], + "SessionStart": [ + { + "hooks": [ + { + "type": "command", + "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/scripts/qring-session-start.sh" + } + ] + } + ] + } +} diff --git a/claude-code-plugin/.claude/skills/exec-with-secrets/SKILL.md b/claude-code-plugin/.claude/skills/exec-with-secrets/SKILL.md new file mode 100644 index 0000000..5c107d8 --- /dev/null +++ b/claude-code-plugin/.claude/skills/exec-with-secrets/SKILL.md @@ -0,0 +1,30 @@ +--- +name: exec-with-secrets +description: Run shell commands with secrets injected from q-ring with stdout/stderr redaction and policy checks. Use when the user wants to run tests, migrations, or CLIs that need API keys without pasting secrets into the shell or .env. +--- + +# Exec with Secrets (MCP) + +## When to use + +- Running a project script that reads env vars you keep in q-ring +- One-off CLI tools (`curl`, SDK CLIs) that need a token from the keyring +- CI-like commands where redaction and `policy.exec` matter + +## Tool + +| Task | MCP tool | +|------|----------| +| Run command with env from q-ring | `exec_with_secrets` | + +## Workflow + +1. Call `get_policy_summary` if unsure whether `exec_with_secrets` is allowed (`policy.mcp` may deny this tool). +2. Prefer `check_policy` with `action: "exec"` when experimenting with deny/allow rules. +3. Call `exec_with_secrets` with the argv array, `projectPath`, and optional key filters so only required secrets are loaded. + +## Safety + +- Never log raw command output to public channels without reviewing redaction limits. +- Prefer `tunnel_create` / `tunnel_read` for one-off handoff of a single value to another agent when full `exec` is unnecessary. +- Use exec profiles (`restricted`, `ci`, `unrestricted`) to bound command behavior. diff --git a/claude-code-plugin/.claude/skills/project-onboarding/SKILL.md b/claude-code-plugin/.claude/skills/project-onboarding/SKILL.md new file mode 100644 index 0000000..0d8fc36 --- /dev/null +++ b/claude-code-plugin/.claude/skills/project-onboarding/SKILL.md @@ -0,0 +1,87 @@ +--- +name: project-onboarding +description: Set up q-ring for a new project — create manifests, detect environments, import secrets, configure hooks and policy. Use when the user starts a new project, mentions .q-ring.json, project manifest, environment detection, or initial secret setup. +--- + +# Project Onboarding + +## When to use + +Activate when the user: +- Starts a new project and needs secret management +- Asks about `.q-ring.json` configuration +- Wants to detect or configure environments +- Needs to set up hooks for secret change notifications +- Asks about governance policy + +## Workflow + +### 1. Detect environment + +Call `detect_environment` to determine the current context. Sources checked in order: +1. Explicit `QRING_ENV` +2. `NODE_ENV` (mapped: `production` → `prod`, `development` → `dev`) +3. Git branch + `.q-ring.json` `branchMap` (supports globs like `release/*`) +4. `.q-ring.json` `defaultEnv` + +### 2. Check existing state + +Call `check_project` to validate against any existing `.q-ring.json` manifest. This reports: +- Required secrets that are present, missing, expired, or stale +- Overall project readiness + +### 3. Create or update the manifest + +Help the user create a `.q-ring.json` file with: + +```json +{ + "env": "dev", + "defaultEnv": "dev", + "branchMap": { + "main": "prod", + "develop": "dev", + "release/*": "staging" + }, + "secrets": { + "DATABASE_URL": { "required": true, "description": "PostgreSQL connection string" }, + "API_KEY": { "required": true, "provider": "openai", "description": "OpenAI API key" } + }, + "policy": { + "mcp": { "denyTools": ["exec_with_secrets"] }, + "secrets": { "maxTtlSeconds": 2592000 } + } +} +``` + +### 4. Import existing secrets + +If the project has `.env` files, offer to import them with `import_dotenv`. Use `skipExisting: true` to avoid overwriting. + +### 5. Generate `.env` from manifest + +Call `env_generate` to produce a `.env` file from the manifest with all declared secrets resolved from q-ring. + +### 6. Set up hooks + +Call `register_hook` to set up notifications when secrets change: +- Shell hook: restart dev server on DB credential change +- HTTP hook: notify a deployment webhook +- Signal hook: send SIGHUP to a running process + +Use `list_hooks` to inspect the registry and `remove_hook` to delete entries by id. + +### 7. Configure policy + +Guide the user through the `policy` section of `.q-ring.json`: +- **mcp**: `allowTools` / `denyTools`, `readableKeys` / `deniedKeys`, `deniedTags` +- **exec**: `allowCommands` / `denyCommands`, `maxRuntimeSeconds`, `allowNetwork` +- **secrets**: `requireApprovalForTags`, `maxTtlSeconds` + +Call `get_policy_summary` to verify the policy is loaded correctly. + +## Best practices + +- Always create a `.q-ring.json` manifest for team projects — it serves as documentation and validation +- Use `branchMap` to automatically detect environments from git branches +- Set `required: true` on critical secrets so `check_project` catches missing credentials diff --git a/claude-code-plugin/.claude/skills/secret-management/SKILL.md b/claude-code-plugin/.claude/skills/secret-management/SKILL.md new file mode 100644 index 0000000..a180f60 --- /dev/null +++ b/claude-code-plugin/.claude/skills/secret-management/SKILL.md @@ -0,0 +1,64 @@ +--- +name: secret-management +description: Manage secrets stored in q-ring — store, retrieve, list, inspect, import, export, and configure superposition, decay, entanglement, and tags. Use when the user mentions secrets, API keys, tokens, credentials, environment variables, .env files, or asks to store/retrieve/delete a value securely. +--- + +# Secret Management + +## When to use + +Activate when the user: +- Asks to store, retrieve, delete, or list secrets +- Mentions API keys, tokens, passwords, credentials, or environment variables +- Wants to import from or export to `.env` files +- Needs superposition (per-environment values) or entanglement (linked secrets) +- Asks about secret expiry, TTL, tags, or access history + +## Workflow + +### 1. Understand the landscape + +Call `get_project_context` to get a redacted overview of existing secrets, scopes, manifest status, and recent activity. + +### 2. CRUD operations + +| Task | MCP Tool | +|------|----------| +| Store a secret | `set_secret` with optional `ttlSeconds`, `tags`, `description`, `env` (superposition), `rotationFormat` | +| Retrieve a secret | `get_secret` — collapses superposition automatically | +| Check existence | `has_secret` — never reveals the value | +| Delete a secret | `delete_secret` | +| List all secrets | `list_secrets` — filter with `tag`, `expired`, `stale`, `filter` | +| Inspect metadata | `inspect_secret` — shows decay, entanglement, access history (no value) | +| Usage / optimization | `analyze_secrets` — JSON report on secret usage patterns | + +`get_secret`, `list_secrets`, and related tools return **JSON** text payloads (not raw unwrapped strings) for predictable agent parsing. + +### 3. Import and export + +- **Import**: `import_dotenv` to bulk-load from `.env` content +- **Export**: `export_secrets` with format `env` or `json`, optional key/tag filters + +### 4. Superposition (multi-environment) + +Store per-environment values with the `env` parameter on `set_secret`: +- `set_secret(key="DB_URL", value="...", env="dev")` +- `set_secret(key="DB_URL", value="...", env="prod")` +- `get_secret` collapses to the detected environment automatically + +### 5. Entanglement + +Link secrets so rotating one updates the other: +- `entangle_secrets(sourceKey, targetKey)` — bidirectional link +- `disentangle_secrets(sourceKey, targetKey)` — remove link + +### 6. Scopes + +Secrets resolve through a cascade: project → team → org → global. Use the `scope` parameter to target a specific level. + +## Best practices + +- Always add a `description` when storing secrets for discoverability +- Use `tags` to group related secrets (e.g., `database`, `api`, `auth`) +- Set `ttlSeconds` for credentials that expire (forces rotation awareness) +- Use `generate_secret` to create high-entropy values instead of inventing them diff --git a/claude-code-plugin/.claude/skills/secret-rotation/SKILL.md b/claude-code-plugin/.claude/skills/secret-rotation/SKILL.md new file mode 100644 index 0000000..88c91e6 --- /dev/null +++ b/claude-code-plugin/.claude/skills/secret-rotation/SKILL.md @@ -0,0 +1,65 @@ +--- +name: secret-rotation +description: Validate, rotate, and batch-check secrets against their providers. Use when the user mentions expired keys, secret rotation, validation, CI secret checks, stale credentials, or provider liveness testing. +--- + +# Secret Rotation and Validation + +## When to use + +Activate when the user: +- Mentions expired, stale, or invalid secrets +- Asks to rotate or refresh API keys +- Wants to validate that secrets are still working +- Needs CI-friendly batch validation +- Asks about secret health or decay status + +## Workflow + +### 1. Health check + +Call `health_check` to get a full report of all secrets: +- **Expired** — TTL elapsed or `expiresAt` passed +- **Stale** — over 75% of lifetime consumed +- **Healthy** — within acceptable range +- Also returns anomaly count and overall status + +### 2. Validate individual secrets + +Call `validate_secret` with a key name. Supported providers with auto-detection: +- **OpenAI** — keys starting with `sk-` +- **Stripe** — keys starting with `sk_live_` or `sk_test_` +- **GitHub** — tokens starting with `ghp_`, `gho_`, `ghs_` +- **AWS** — keys starting with `AKIA` +- **Generic HTTP** — any URL-based validation endpoint + +Returns: `valid`, `invalid`, `error`, or `unknown` with latency and provider info. + +### 3. Rotate expired secrets + +Call `rotate_secret` with the key name. q-ring will: +- Attempt provider-native rotation if a provider is configured +- Fall back to local generation using the secret's `rotationFormat` and `rotationPrefix` +- Update the stored value and fire any registered hooks + +### 4. Batch CI validation + +Call `ci_validate_secrets` for a structured pass/fail report suitable for CI pipelines. Returns: +- Per-secret validation results +- Rotation recommendations +- Overall pass/fail status + +### 5. List available providers + +Call `list_providers` to see all supported validation providers with their prefix patterns and descriptions. + +### 6. Dashboard and autonomous scans + +- **`status_dashboard`** — starts the local quantum status dashboard (browser UI on localhost). +- **`agent_scan`** — one-shot health scan JSON (same family as CLI `qring agent --once`). + +## Best practices + +- Store secrets with `rotationFormat` (e.g., `api-key`, `password`, `uuid`) to enable automatic rotation +- Set `provider` metadata for automatic validation detection +- Run `ci_validate_secrets` in CI pipelines to catch expired credentials before deployment diff --git a/claude-code-plugin/.claude/skills/secret-scanning/SKILL.md b/claude-code-plugin/.claude/skills/secret-scanning/SKILL.md new file mode 100644 index 0000000..4f3d21d --- /dev/null +++ b/claude-code-plugin/.claude/skills/secret-scanning/SKILL.md @@ -0,0 +1,53 @@ +--- +name: secret-scanning +description: Scan and lint codebases for hardcoded secrets using entropy analysis and regex heuristics. Use when the user asks to find leaked credentials, audit code for secrets, migrate hardcoded values to q-ring, or clean up a codebase before committing. +--- + +# Secret Scanning + +## When to use + +Activate when the user: +- Asks to scan a project for hardcoded secrets or credentials +- Wants to audit code before a commit or PR +- Needs to migrate hardcoded values from source files into q-ring +- Mentions "secret leak", "credential scan", or "lint for secrets" + +## Workflow + +### 1. Scan the codebase + +Call `scan_codebase_for_secrets` with the project directory. The scanner uses: +- Regex heuristics matching common patterns (`api_key`, `secret`, `token`, `password`, etc.) +- Shannon entropy analysis (flags values with entropy > 3.5) +- Known prefix detection (`sk-`, `ghp_`, etc.) + +It automatically skips `node_modules`, `.git`, binary files, lockfiles, and minified code. + +### 2. Review findings + +Each result includes: +- `file` and `line` — location +- `keyName` — the detected variable name +- `match` — the suspicious value +- `entropy` — Shannon entropy score +- `context` — the full line of code + +Present findings grouped by file. Highlight high-entropy matches (> 4.0) as most likely to be real secrets. + +### 3. Auto-fix with lint + +Call `lint_files` with the list of affected files and `fix: true` to: +- Replace hardcoded values with `process.env.KEY` references (language-aware) +- Store the extracted values in q-ring automatically +- Support JS/TS, Python, Ruby, Go, Rust, Java, Kotlin, C#, PHP, and Shell + +### 4. Verify cleanup + +After fixing, re-run `scan_codebase_for_secrets` to confirm no secrets remain. + +## Best practices + +- Run scanning before every PR or commit +- Ignore placeholder values (`your_api_key`, `replace_me`, `example`) — the scanner handles this automatically +- For files with false positives, values under 8 characters or with low entropy are already filtered diff --git a/claude-code-plugin/.mcp.json b/claude-code-plugin/.mcp.json new file mode 100644 index 0000000..04ee5a1 --- /dev/null +++ b/claude-code-plugin/.mcp.json @@ -0,0 +1,10 @@ +{ + "mcpServers": { + "q-ring": { + "type": "stdio", + "command": "qring-mcp", + "args": [], + "env": {} + } + } +} diff --git a/claude-code-plugin/CLAUDE.md b/claude-code-plugin/CLAUDE.md new file mode 100644 index 0000000..3d8bbe8 --- /dev/null +++ b/claude-code-plugin/CLAUDE.md @@ -0,0 +1,41 @@ +# Claude Code · Project Memory + +> This file is loaded automatically into every Claude Code session in this project. It encodes the always-on q-ring rules. The agents, slash commands, and skills under `.claude/` extend this with on-demand behavior. + +## q-ring · Secret hygiene (always) + +- **Never** hardcode secrets, API keys, tokens, passwords, or connection strings in source code or config files. +- Store secrets using the q-ring MCP tool `set_secret` or the `qring set` CLI — not in `.env` files, inline strings, or comments. +- Reference secrets in code via `process.env.KEY` (JS/TS), `os.environ["KEY"]` (Python), or the language equivalent. The actual value lives in q-ring. +- When reviewing or writing code, flag any string that matches common credential patterns (`sk-*`, `ghp_*`, `Bearer *`, long base64 blobs, connection strings with passwords). +- If you spot a hardcoded secret, run `scan_codebase_for_secrets` followed by `lint_files` with `fix: true` to migrate it into q-ring. +- Secrets with a TTL or rotation format should always be stored with `ttlSeconds` or `rotationFormat` so q-ring can track decay and automate rotation. +- When a shell command would contain a secret value (long base64, `sk-*`, `ghp_*`, etc.), warn the user that secrets must not appear in shell history. Suggest the `/qring-exec-safe` command (`exec_with_secrets` MCP tool) instead. + +## q-ring · Workflow (always) + +- Use q-ring MCP tools (`get_secret`, `set_secret`, `list_secrets`, etc.) for **every** secret operation. Never call OS keychain APIs directly. +- Before working with a project's secrets for the first time, call `get_project_context` to understand what secrets exist, their scopes, and any governance policy. +- If the project has a `.q-ring.json` file, call `check_policy` before tool or exec actions to respect governance rules. +- After writing or deleting a secret, remind the user that q-ring maintains a tamper-evident audit trail accessible via `audit_log`. +- For ephemeral values (one-time tokens, OTPs), use `tunnel_create` instead of `set_secret` — tunnels are memory-only and self-destruct on TTL or read count. +- For sharing secrets across machines, use `teleport_pack` / `teleport_unpack` — never paste raw credentials into chat or files. +- Treat the q-ring MCP server (`q-ring`) as the single source of truth for secret values. Treat `.env` files as derived artifacts produced by `env_generate`. + +## q-ring · `.env` file safety (when a `.env*` file is in scope) + +When a `.env`, `.env.local`, `.env.production`, or similar file is open or being edited: + +1. **Suggest importing.** Offer to call `import_dotenv` to migrate all key-value pairs into q-ring where they are encrypted in the OS keychain. +2. **Check `.gitignore`.** Verify that `.env*` patterns are in `.gitignore`. If not, warn immediately and offer to add them. +3. **Prefer manifest-driven generation.** If the project has a `.q-ring.json` manifest, suggest `env_generate` to produce `.env` files on-demand from q-ring instead of maintaining them by hand. +4. **Never add new secrets** to `.env` files directly. Use `set_secret` (or `qring set KEY value`) and then `env_generate` to produce the file. + +## Available extensions + +- **Subagents** under `.claude/agents/` — `secret-ops` (CRUD/transfer assistant) and `security-auditor` (proactive monitoring). +- **Slash commands** under `.claude/commands/` — `/qring-scan-secrets`, `/qring-health-check`, `/qring-rotate-expired`, `/qring-setup-project`, `/qring-teleport-secrets`, `/qring-dashboard`, `/qring-exec-safe`, `/qring-analyze`. +- **Skills** under `.claude/skills/` — auto-triggered by topic: `secret-management`, `secret-scanning`, `secret-rotation`, `project-onboarding`, `exec-with-secrets`. +- **Hooks** in `.claude/settings.json` — lint reminders after edits, `.env` commit guards, session-start context hint. + +The MCP server `q-ring` (configured in `.mcp.json`) exposes 44 tools for secrets, scanning, rotation, auditing, and governance. diff --git a/claude-code-plugin/README.md b/claude-code-plugin/README.md new file mode 100644 index 0000000..64064e0 --- /dev/null +++ b/claude-code-plugin/README.md @@ -0,0 +1,158 @@ +# q-ring Claude Code Plugin + +Quantum keyring for AI agents — manage secrets, scan for leaks, rotate keys, and enforce policy directly from [Claude Code](https://docs.claude.com/en/docs/claude-code/overview). + +This package mirrors the q-ring [Cursor plugin](../cursor-plugin/README.md) for Claude Code's native primitives: project [memory](https://docs.claude.com/en/docs/claude-code/memory) (`CLAUDE.md`), [subagents](https://docs.claude.com/en/docs/claude-code/sub-agents), [slash commands](https://docs.claude.com/en/docs/claude-code/slash-commands), [skills](https://docs.claude.com/en/docs/claude-code/skills), [hooks](https://docs.claude.com/en/docs/claude-code/hooks), and [project-scoped MCP](https://docs.claude.com/en/docs/claude-code/mcp). + +## Prerequisites + +Install the q-ring CLI and MCP server globally: + +```bash +# pnpm (recommended) +pnpm add -g @i4ctime/q-ring + +# npm +npm install -g @i4ctime/q-ring + +# Homebrew +brew install i4ctime/tap/qring +``` + +Verify the MCP server is on `PATH`: + +```bash +qring-mcp --help +``` + +## What's Included + +### Project memory (`CLAUDE.md`) + +Loaded into every Claude Code conversation in this project. Provides the always-on rules — never hardcode secrets, use q-ring for all operations, and warn about `.env` files. Equivalent to `cursor-plugin/rules/*.mdc`. + +### MCP server (`.mcp.json`) + +Project-scoped MCP config that connects Claude Code to the local `qring-mcp` binary over stdio. All 44 q-ring MCP tools become available in chat. + +### Subagents (`.claude/agents/*.md`) + +| Subagent | Purpose | +|----------|---------| +| `secret-ops` | Day-to-day secret operations — store, share, organize, generate | +| `security-auditor` | Proactive security monitoring — audit trails, anomalies, governance | + +Invoke explicitly with `> Use the secret-ops subagent to store my OpenAI key` or let Claude Code delegate automatically based on the description. + +### Slash commands (`.claude/commands/*.md`) + +| Command | Action | +|---------|--------| +| `/qring-scan-secrets` | Scan codebase for hardcoded secrets, offer auto-fix | +| `/qring-health-check` | Full health report — decay, anomalies, audit integrity | +| `/qring-rotate-expired` | Find and rotate expired/stale credentials | +| `/qring-setup-project` | Initialize q-ring — manifest, imports, hooks | +| `/qring-teleport-secrets` | Encrypted cross-machine secret transfer | +| `/qring-dashboard` | Launch the live status dashboard (SSE + browser) | +| `/qring-exec-safe` | Run a command with secrets injected and stdout/stderr redacted | +| `/qring-analyze` | Usage analytics and optimization suggestions | + +### Skills (`.claude/skills/*/SKILL.md`) + +| Skill | Triggers On | +|-------|-------------| +| `secret-management` | Mentions of secrets, API keys, tokens, credentials, `.env` files | +| `secret-scanning` | Requests to scan, lint, audit, or find leaked credentials | +| `secret-rotation` | Expired keys, rotation, validation, CI checks | +| `project-onboarding` | New project setup, manifests, environment detection | +| `exec-with-secrets` | Running commands that need API keys without pasting them | + +Skills are progressively disclosed — Claude Code reads only the metadata until a skill is relevant, then loads the full body. + +### Hooks (`.claude/settings.json`) + +| Event | Behavior | +|-------|----------| +| `PostToolUse` (`Write\|Edit\|MultiEdit`) | Log a reminder to lint the edited file with `lint_files` MCP tool | +| `PreToolUse` (`Bash`) | Block commands that look like they would commit / print `.env` files; warn about secret leakage | +| `SessionStart` | Print a one-line reminder to call `get_project_context` if a `.q-ring.json` is detected | + +> Hook scripts live in `hooks/scripts/`. They are pure Bash with no runtime dependencies — safe to read before installing. + +## Installation + +### One-shot sync (recommended) + +From the `quantum_ring` repo root: + +```bash +pnpm install +pnpm run plugin:sync:claude +``` + +This copies into your project (`$PWD` by default): + +- `claude-code-plugin/CLAUDE.md` → `./CLAUDE.md` +- `claude-code-plugin/.mcp.json` → `./.mcp.json` +- `claude-code-plugin/.claude/` → `./.claude/` + +Pass a custom destination as the first argument: + +```bash +pnpm run plugin:sync:claude -- /path/to/your/project +``` + +### User-level install + +To install the agents, commands, skills, and hooks for **all** projects (instead of one project), copy into `~/.claude/`: + +```bash +mkdir -p ~/.claude +cp -r claude-code-plugin/.claude/agents ~/.claude/agents +cp -r claude-code-plugin/.claude/commands ~/.claude/commands +cp -r claude-code-plugin/.claude/skills ~/.claude/skills +cp claude-code-plugin/.claude/settings.json ~/.claude/settings.json +``` + +Add the MCP server globally with the Claude Code CLI: + +```bash +claude mcp add q-ring -- qring-mcp +``` + +> User-scoped commands are invoked the same way as project commands (e.g. `/qring-scan-secrets`); subagents are accessible from any project. + +### Manual project install + +```bash +cp -r claude-code-plugin/.claude . +cp claude-code-plugin/CLAUDE.md CLAUDE.md +cp claude-code-plugin/.mcp.json .mcp.json +``` + +The first time you run `claude` in this project it will prompt you to approve the project-scoped MCP server defined in `.mcp.json`. + +## Configuration + +The plugin works out of the box. For project-specific behavior, create a `.q-ring.json` manifest in your project root: + +```json +{ + "env": "dev", + "defaultEnv": "dev", + "branchMap": { + "main": "prod", + "develop": "dev" + }, + "secrets": { + "DATABASE_URL": { "required": true, "description": "PostgreSQL connection string" }, + "API_KEY": { "required": true, "provider": "openai" } + } +} +``` + +Or run `/qring-setup-project` and let the agent walk you through it. + +## License + +AGPL-3.0-only — same as the [@i4ctime/q-ring](https://www.npmjs.com/package/@i4ctime/q-ring) npm package and [quantum_ring](https://github.com/I4cTime/quantum_ring) repository. diff --git a/cursor-plugin/.cursor-plugin/plugin.json b/cursor-plugin/.cursor-plugin/plugin.json index 8479c40..f86e029 100644 --- a/cursor-plugin/.cursor-plugin/plugin.json +++ b/cursor-plugin/.cursor-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "qring", "description": "Quantum keyring for AI agents — manage secrets, scan for leaks, rotate keys, and enforce policy directly from Cursor.", - "version": "0.10.1", + "version": "0.11.5", "author": { "name": "I4cTime" }, @@ -20,5 +20,5 @@ "secret-rotation", "governance" ], - "logo": "https://raw.githubusercontent.com/I4cTime/quantum_ring/main/web/public/assets/logo.png" + "logo": "https://raw.githubusercontent.com/I4cTime/quantum_ring/main/assets/logo.png" } diff --git a/cursor-plugin/README.md b/cursor-plugin/README.md index f184a55..e785f1d 100644 --- a/cursor-plugin/README.md +++ b/cursor-plugin/README.md @@ -2,6 +2,8 @@ Quantum keyring for AI agents — manage secrets, scan for leaks, rotate keys, and enforce policy directly from Cursor. +> **Looking for another editor?** See the sister packs: [`kiro-plugin/`](../kiro-plugin/README.md) for [Kiro](https://kiro.dev) and [`claude-code-plugin/`](../claude-code-plugin/README.md) for [Claude Code](https://docs.claude.com/en/docs/claude-code/overview). + ## Prerequisites Install the q-ring CLI and MCP server globally: diff --git a/eslint.config.mjs b/eslint.config.mjs index 0b94a82..1341853 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -5,7 +5,7 @@ export default tseslint.config( eslint.configs.recommended, ...tseslint.configs.recommended, { - ignores: ["dist/**", "node_modules/**", "web/**", "coverage/**"], + ignores: ["dist/**", "node_modules/**", "coverage/**"], }, { rules: { diff --git a/kiro-plugin/POWER.md b/kiro-plugin/POWER.md new file mode 100644 index 0000000..070947a --- /dev/null +++ b/kiro-plugin/POWER.md @@ -0,0 +1,110 @@ +--- +name: "q-ring" +displayName: "q-ring — quantum keyring for AI agents" +description: "Secure secrets in the OS keychain with superposition, entanglement, audit trails, and 44 MCP tools — store and retrieve API keys, scan for leaks, rotate credentials, and enforce policy without pasting secrets into .env or chat." +keywords: + - "q-ring" + - "qring" + - "secrets" + - "api key" + - "api keys" + - "credentials" + - "environment variables" + - "dotenv" + - ".env" + - "keyring" + - "MCP" + - "token" + - "password" + - "rotation" + - "secret scanning" + - "vault" +author: "I4cTime" +--- + +# q-ring Power for Kiro + +This power follows the official [Create powers](https://kiro.dev/docs/powers/create/) layout: `POWER.md`, root `mcp.json`, and `steering/`. Optional workspace hooks live in `hooks/` for onboarding copy into `.kiro/hooks/`. + +The MCP server key in `mcp.json` is **`q-ring`**. Kiro may namespace it when the power loads; refer to whatever server name appears in the MCP panel when calling tools. + +## Onboarding + +### Step 1: Install q-ring and verify MCP + +The power expects the q-ring CLI and MCP binary on your `PATH`: + +```bash +pnpm add -g @i4ctime/q-ring +# or: npm install -g @i4ctime/q-ring +# or: brew install i4ctime/tap/qring +``` + +Verify: + +```bash +qring-mcp --help +``` + +**CRITICAL:** If `qring-mcp` is not found, do **not** pretend q-ring tools work — tell the user to install `@i4ctime/q-ring` globally (or run from a local `quantum_ring` clone with `node dist/mcp.js`) and reload MCP in Kiro. + +### Step 2: Add this folder as a Kiro Power (recommended) + +1. Open Kiro → **Powers** panel → **Add power from Local Path**. +2. Select the `kiro-plugin` directory from the [quantum_ring](https://github.com/I4cTime/quantum_ring) repository (the folder that contains `POWER.md`, `mcp.json`, and `steering/`). +3. Confirm the power activates when the user mentions secrets, `.env`, API keys, or q-ring (see `keywords` in frontmatter). + +To share publicly: push the `kiro-plugin/` tree to a public GitHub repo and others can use **Add power from GitHub** per [Create powers — Sharing your power](https://kiro.dev/docs/powers/create/). Curated community powers are listed at [github.com/kirodotdev/powers](https://github.com/kirodotdev/powers). + +### Step 3 (optional): Workspace hooks + +Copy the JSON hook files from this power’s `hooks/` directory into the workspace `.kiro/hooks/` if the user wants save-time linting and `.env` guards: + +- `hooks/qring-scan-on-save.kiro.hook` — after saving source files, suggest `lint_files` for hardcoded secrets. +- `hooks/qring-env-file-edit.kiro.hook` — after editing `.env*`, suggest `import_dotenv` and `.gitignore` checks. +- `hooks/qring-session-init.kiro.hook` — manual button to run `get_project_context`. + +If copying fails or the schema changes, recreate the same prompts from the hook `then.prompt` fields in the Kiro **Agent Hooks** UI. + +### Alternative: Flatten into `~/.kiro` (no Power UI) + +From the `quantum_ring` repo root: + +```bash +pnpm run plugin:sync:kiro +``` + +This copies `mcp.json` → `~/.kiro/settings/mcp.json`, plus `steering/` and `hooks/` into the user’s `.kiro` tree. Use `--force` to overwrite an existing `mcp.json`, or merge the generated `mcp.json.qring-template` by hand. + +## When to load steering files + +Use the steering files under `steering/` for focused context. Reference them with `#filename` in chat (without `.md`) when you need that workflow, or rely on `inclusion: always` / `fileMatch` files when this power is installed into `.kiro/steering/` via `plugin:sync:kiro`. + +| Situation | Steering file | +|-----------|----------------| +| Always-on secret hygiene (never hardcode) | `qring-secret-hygiene.md` | +| Always-on MCP / workflow for q-ring | `qring-workflow.md` | +| User has `.env` or `.env.*` open | `qring-env-file-safety.md` | +| Day-to-day store / retrieve / tunnels / teleport | `qring-secret-ops.md` | +| Audit, anomalies, policy, leak scan | `qring-security-auditor.md` | +| CRUD, import/export, superposition, entanglement | `qring-secret-management.md` | +| Scan or lint repo for hardcoded secrets | `qring-secret-scanning.md` | +| Health, validate, rotate, CI checks | `qring-secret-rotation.md` | +| `.q-ring.json`, manifest, hooks, policy | `qring-project-onboarding.md` | +| Run commands with injected + redacted env | `qring-exec-with-secrets.md` | +| Command-style: scan repo | `qring-cmd-scan-secrets.md` | +| Command-style: health report | `qring-cmd-health-check.md` | +| Command-style: rotate expired/stale | `qring-cmd-rotate-expired.md` | +| Command-style: bootstrap project | `qring-cmd-setup-project.md` | +| Command-style: teleport bundle | `qring-cmd-teleport-secrets.md` | +| Command-style: status dashboard | `qring-cmd-dashboard.md` | +| Command-style: exec with redaction | `qring-cmd-exec-safe.md` | +| Command-style: usage analytics | `qring-cmd-analyze.md` | + +## Best practices (summary) + +- Prefer q-ring MCP tools (`get_secret`, `set_secret`, `scan_codebase_for_secrets`, …) over pasting secrets into chat or plain-text `.env` files. +- Call `get_project_context` before bulk secret work to get a redacted manifest/policy view. +- For one-off values, use `tunnel_create`; for machine-to-machine transfer, use `teleport_pack` / `teleport_unpack`. + +Full install notes and tables live in [`README.md`](README.md) in this directory. diff --git a/kiro-plugin/README.md b/kiro-plugin/README.md new file mode 100644 index 0000000..9534821 --- /dev/null +++ b/kiro-plugin/README.md @@ -0,0 +1,153 @@ +# q-ring Kiro Power + +Quantum keyring for AI agents — manage secrets, scan for leaks, rotate keys, and enforce policy directly from [Kiro](https://kiro.dev). + +This directory is a Kiro **Power** as defined in [Create powers](https://kiro.dev/docs/powers/create/): + +| Required / optional | File or folder | Role | +|---------------------|----------------|------| +| Required | [`POWER.md`](POWER.md) | Frontmatter (`name`, `displayName`, `description`, `keywords`, `author`), onboarding, steering map | +| Optional | [`mcp.json`](mcp.json) | MCP server config — server key **`q-ring`** matches tool references in steering | +| Optional | [`steering/`](steering/) | Workflow-specific guidance (same content as before; `inclusion` applies when synced to `.kiro/steering/`) | +| Optional | [`hooks/`](hooks/) | Agent hook JSON — copy into workspace `.kiro/hooks/` during onboarding | + +It mirrors the q-ring [Cursor plugin](../cursor-plugin/README.md) for Kiro’s [MCP](https://kiro.dev/docs/mcp/), [steering](https://kiro.dev/docs/steering/), and [hooks](https://kiro.dev/docs/hooks/). + +## Prerequisites + +Install the q-ring CLI and MCP server globally: + +```bash +# pnpm (recommended) +pnpm add -g @i4ctime/q-ring + +# npm +npm install -g @i4ctime/q-ring + +# Homebrew +brew install i4ctime/tap/qring +``` + +Verify the MCP server is on `PATH`: + +```bash +qring-mcp --help +``` + +## What's Included + +### MCP server (`mcp.json` at power root) + +When you add this folder as a Power, Kiro loads [`mcp.json`](mcp.json) from the power root (per [Adding MCP servers](https://kiro.dev/docs/powers/create/)). It connects to the local `qring-mcp` binary over stdio so all 44 q-ring MCP tools are available — `get_secret`, `set_secret`, `scan_codebase_for_secrets`, `rotate_secret`, `health_check`, and so on. + +If you use **`pnpm run plugin:sync:kiro`** instead, the same file is copied to **`.kiro/settings/mcp.json`** (Kiro’s user-level MCP location for a flattened install). + +### Steering files (`steering/*.md` → `.kiro/steering/`) + +Steering shapes Kiro's behavior the same way Cursor rules do. The frontmatter `inclusion` field controls when each file is loaded. + +| Steering file | Inclusion | Purpose | +|---------------|-----------|---------| +| `qring-secret-hygiene.md` | `always` | Never hardcode secrets — always go through q-ring | +| `qring-workflow.md` | `always` | Use q-ring MCP tools for every secret operation | +| `qring-env-file-safety.md` | `fileMatch` (`**/.env*`) | Warn about `.env` files, suggest importing into q-ring | +| `qring-secret-ops.md` | `manual` | Agent persona — day-to-day secret operations | +| `qring-security-auditor.md` | `manual` | Agent persona — proactive monitoring & governance | +| `qring-secret-management.md` | `manual` | Skill — store/retrieve/list/inspect secrets | +| `qring-secret-scanning.md` | `manual` | Skill — scan and lint codebases for hardcoded secrets | +| `qring-secret-rotation.md` | `manual` | Skill — validate, rotate, and CI-check secrets | +| `qring-project-onboarding.md` | `manual` | Skill — create manifests, detect environments, register hooks | +| `qring-exec-with-secrets.md` | `manual` | Skill — run commands with secrets injected and redacted | +| `qring-cmd-scan-secrets.md` | `manual` | Slash-style command — scan & auto-fix | +| `qring-cmd-health-check.md` | `manual` | Slash-style command — full health report | +| `qring-cmd-rotate-expired.md` | `manual` | Slash-style command — rotate expired/stale credentials | +| `qring-cmd-setup-project.md` | `manual` | Slash-style command — initialize q-ring for a project | +| `qring-cmd-teleport-secrets.md` | `manual` | Slash-style command — encrypted cross-machine transfer | +| `qring-cmd-dashboard.md` | `manual` | Slash-style command — launch the live status dashboard | +| `qring-cmd-exec-safe.md` | `manual` | Slash-style command — exec with redaction | +| `qring-cmd-analyze.md` | `manual` | Slash-style command — usage analytics | + +Manual steering files are activated by typing `#qring-secret-ops` (etc.) in the Kiro chat — Kiro will load that file into context for the conversation. + +### Agent hooks (`hooks/*.kiro.hook` → `.kiro/hooks/`) + +| Hook file | Trigger | Behavior | +|-----------|---------|----------| +| `qring-scan-on-save.kiro.hook` | File saved (source files) | Run `lint_files` MCP tool; warn and offer auto-fix when secrets are detected | +| `qring-env-file-edit.kiro.hook` | File saved (`.env*`) | Suggest `import_dotenv`; verify `.gitignore` covers `.env*` | +| `qring-session-init.kiro.hook` | Manual button | Run `get_project_context`; surface expired or stale secrets | + +> Kiro's hook schema is still maturing. The `.kiro.hook` files in this directory are saved in the JSON format Kiro currently accepts; if Kiro fails to load them, recreate the same logic from the **Agent Hooks** UI using the prompts in each file as the hook body. + +## Installation + +### Recommended: Add as a Kiro Power (local path) + +1. Install `@i4ctime/q-ring` globally and verify `qring-mcp --help` (see **Prerequisites** above). +2. Open Kiro → **Powers** → **Add power from Local Path**. +3. Select this **`kiro-plugin`** directory (the one containing `POWER.md` and `mcp.json`). + +Test activation with phrases that match the keywords in `POWER.md` (e.g. “store this API key in q-ring”, “scan for secrets”, “rotate expired keys”). See [Testing locally](https://kiro.dev/docs/powers/create/). + +### Share on GitHub + +Push the `kiro-plugin/` tree to a **public** repository so others can use **Add power from GitHub** — see [Sharing your power](https://kiro.dev/docs/powers/create/). + +### Alternative: Flatten into `~/.kiro` (no Power UI) + +From the `quantum_ring` repo root: + +```bash +pnpm install +pnpm run plugin:sync:kiro +``` + +This copies: + +- `kiro-plugin/mcp.json` → `~/.kiro/settings/mcp.json` (user-level) +- `kiro-plugin/steering/` → `~/.kiro/steering/` +- `kiro-plugin/hooks/` → `~/.kiro/hooks/` + +Pass a custom destination for a project-scoped flatten: + +```bash +pnpm run plugin:sync:kiro -- /path/to/your/project/.kiro +``` + +If `settings/mcp.json` already exists, the script writes `mcp.json.qring-template` unless you pass `--force`. Merge the q-ring server block by hand or overwrite after review. + +### Manual flatten (project-scoped) + +```bash +mkdir -p .kiro/{settings,steering,hooks} +cp kiro-plugin/mcp.json .kiro/settings/mcp.json +cp kiro-plugin/steering/*.md .kiro/steering/ +cp kiro-plugin/hooks/*.kiro.hook .kiro/hooks/ +``` + +Reload Kiro's MCP servers from the **MCP Servers** panel after copying. + +## Configuration + +The plugin works out of the box. For project-specific behavior, create a `.q-ring.json` manifest in your project root: + +```json +{ + "env": "dev", + "defaultEnv": "dev", + "branchMap": { + "main": "prod", + "develop": "dev" + }, + "secrets": { + "DATABASE_URL": { "required": true, "description": "PostgreSQL connection string" }, + "API_KEY": { "required": true, "provider": "openai" } + } +} +``` + +Or activate the manual steering file `#qring-cmd-setup-project` and let the agent walk you through it. + +## License + +AGPL-3.0-only — same as the [@i4ctime/q-ring](https://www.npmjs.com/package/@i4ctime/q-ring) npm package and [quantum_ring](https://github.com/I4cTime/quantum_ring) repository. diff --git a/kiro-plugin/hooks/qring-env-file-edit.kiro.hook b/kiro-plugin/hooks/qring-env-file-edit.kiro.hook new file mode 100644 index 0000000..49fd0eb --- /dev/null +++ b/kiro-plugin/hooks/qring-env-file-edit.kiro.hook @@ -0,0 +1,17 @@ +{ + "enabled": true, + "name": "q-ring · .env file edit", + "description": "When a .env file is created or edited, suggest importing into q-ring and verify .gitignore.", + "version": "1", + "when": { + "type": "fileEdited", + "patterns": [ + "**/.env", + "**/.env.*" + ] + }, + "then": { + "type": "askAgent", + "prompt": "A .env file was just edited. (1) Verify that `.env*` patterns are present in the project's `.gitignore`; if not, warn the user and offer to add them. (2) Offer to call the q-ring MCP tool `import_dotenv` (with `skipExisting: true`) to migrate the values into q-ring where they are encrypted in the OS keychain. (3) If the project has a `.q-ring.json` manifest, suggest `env_generate` for future regeneration. Never echo the .env values back to the user." + } +} diff --git a/kiro-plugin/hooks/qring-scan-on-save.kiro.hook b/kiro-plugin/hooks/qring-scan-on-save.kiro.hook new file mode 100644 index 0000000..96cc2ac --- /dev/null +++ b/kiro-plugin/hooks/qring-scan-on-save.kiro.hook @@ -0,0 +1,34 @@ +{ + "enabled": true, + "name": "q-ring · Scan on save", + "description": "After a source file is saved, lint it for hardcoded secrets via q-ring and offer to auto-fix.", + "version": "1", + "when": { + "type": "fileEdited", + "patterns": [ + "**/*.ts", + "**/*.tsx", + "**/*.js", + "**/*.jsx", + "**/*.mjs", + "**/*.cjs", + "**/*.py", + "**/*.go", + "**/*.rs", + "**/*.rb", + "**/*.java", + "**/*.kt", + "**/*.cs", + "**/*.php", + "**/*.sh", + "**/*.json", + "**/*.yml", + "**/*.yaml", + "**/*.md" + ] + }, + "then": { + "type": "askAgent", + "prompt": "A file in this workspace was just saved. Call the q-ring MCP tool `lint_files` for the saved file(s) (do NOT scan the entire repo). If hardcoded secrets are found, summarize the findings concisely and ask whether to call `lint_files` again with `fix: true` to migrate them into q-ring (replacing literal values with `process.env.KEY` style references). Skip binary assets, lockfiles, minified bundles, and anything under `node_modules`, `dist`, `build`, `.git`, or `coverage`." + } +} diff --git a/kiro-plugin/hooks/qring-session-init.kiro.hook b/kiro-plugin/hooks/qring-session-init.kiro.hook new file mode 100644 index 0000000..18c80b9 --- /dev/null +++ b/kiro-plugin/hooks/qring-session-init.kiro.hook @@ -0,0 +1,14 @@ +{ + "enabled": true, + "name": "q-ring · Session init", + "description": "Manual button: load the project's q-ring context — secrets, manifest, policy, expired keys.", + "version": "1", + "when": { + "type": "userTriggered", + "buttonLabel": "q-ring: load project context" + }, + "then": { + "type": "askAgent", + "prompt": "Call the q-ring MCP tool `get_project_context` for the current workspace. Summarize: detected environment, declared manifest secrets (present / missing / expired / stale), policy posture (mcp / exec / secrets), and any anomalies. Do NOT print any secret values. End with one or two concrete next-step suggestions (e.g. `#qring-cmd-rotate-expired` if anything is expired, `#qring-cmd-setup-project` if there is no manifest)." + } +} diff --git a/kiro-plugin/mcp.json b/kiro-plugin/mcp.json new file mode 100644 index 0000000..e4ce494 --- /dev/null +++ b/kiro-plugin/mcp.json @@ -0,0 +1,24 @@ +{ + "mcpServers": { + "q-ring": { + "command": "qring-mcp", + "args": [], + "env": {}, + "disabled": false, + "autoApprove": [ + "list_secrets", + "has_secret", + "inspect_secret", + "detect_environment", + "get_project_context", + "list_providers", + "list_hooks", + "get_policy_summary", + "audit_log", + "verify_audit_chain", + "health_check", + "analyze_secrets" + ] + } + } +} diff --git a/kiro-plugin/steering/qring-cmd-analyze.md b/kiro-plugin/steering/qring-cmd-analyze.md new file mode 100644 index 0000000..f635ed5 --- /dev/null +++ b/kiro-plugin/steering/qring-cmd-analyze.md @@ -0,0 +1,14 @@ +--- +inclusion: manual +--- + +# q-ring · Analyze (command) + +> Activate by typing `#qring-cmd-analyze` in chat. + +Run q-ring secret usage / optimization analysis. Use when the user asks how secrets are used, which keys are stale, or for cleanup suggestions. + +## Workflow + +1. Call MCP tool `analyze_secrets` with the relevant `projectPath` / scope options. +2. Summarize the JSON: heavy keys, unused entries, decay risks, and concrete next steps. diff --git a/kiro-plugin/steering/qring-cmd-dashboard.md b/kiro-plugin/steering/qring-cmd-dashboard.md new file mode 100644 index 0000000..632d96a --- /dev/null +++ b/kiro-plugin/steering/qring-cmd-dashboard.md @@ -0,0 +1,38 @@ +--- +inclusion: manual +--- + +# q-ring · Dashboard (command) + +> Activate by typing `#qring-cmd-dashboard` in chat. + +Start the q-ring local status dashboard (SSE + browser UI). Use when the user wants a live view of secret health, manifest gaps, policy posture, approvals, hooks, and audit traffic without exposing secret values. + +## Workflow + +1. Call MCP tool `status_dashboard`. +2. Open the returned `http://127.0.0.1:…` URL in a browser (local only — bound to loopback). + +If the dashboard is already running, the tool reports the existing URL instead of starting a second listener. + +## What the page shows + +- **KPI strip** — total secrets, detected env, protected count, active approvals, hooks, 24h reads/writes, denied actions, and live anomaly count. +- **Health summary** — donut of healthy / stale / expired / no-decay secrets with per-scope breakdown. +- **Environment** — wavefunction collapse details (env, source, branch). +- **Manifest** — declared / required / missing / expired / stale keys from `.q-ring.json`. +- **Policy** — MCP / exec / secret policy presence with allow-deny / approval / rotation counts. +- **Secrets table** — sortable, searchable view of every secret with quick chips for `expired`, `stale`, `protected`. +- **Quantum cards** — decay timers, superposition states, entanglement pairs, active tunnels. +- **Approvals & hooks** — live grants and registered hooks with tamper / expiry state and match summaries. +- **Agent memory** — count of encrypted memory keys. +- **Anomaly alerts + audit feed** — filterable by action and source with free-text search. + +## Controls + +- Top bar: pause SSE updates, force refresh, jump to raw JSON (`/api/status`). +- Keyboard: `/` focus secrets search · `P` pause · `R` refresh · `Esc` blur input. + +## Important + +The dashboard never renders secret **values** — only metadata. It is safe to share a screenshot for debugging, but the bound URL stays on `127.0.0.1` and should not be exposed beyond the local machine. diff --git a/kiro-plugin/steering/qring-cmd-exec-safe.md b/kiro-plugin/steering/qring-cmd-exec-safe.md new file mode 100644 index 0000000..e605bc1 --- /dev/null +++ b/kiro-plugin/steering/qring-cmd-exec-safe.md @@ -0,0 +1,17 @@ +--- +inclusion: manual +--- + +# q-ring · Exec Safe (command) + +> Activate by typing `#qring-cmd-exec-safe` in chat. + +Run a shell command with q-ring injected secrets and redaction. Use when the user needs to run builds/tests/tools that require env vars stored in q-ring. + +## Workflow + +1. Confirm `get_policy_summary` / `check_policy` allows `exec_with_secrets` for this project. +2. Call `exec_with_secrets` with explicit argv (array), working directory, and minimal secret scope. +3. Present stdout/stderr safely; never repeat suspected secret substrings in follow-up messages. + +See skill `#qring-exec-with-secrets` for full patterns. diff --git a/kiro-plugin/steering/qring-cmd-health-check.md b/kiro-plugin/steering/qring-cmd-health-check.md new file mode 100644 index 0000000..33e3c3d --- /dev/null +++ b/kiro-plugin/steering/qring-cmd-health-check.md @@ -0,0 +1,27 @@ +--- +inclusion: manual +--- + +# q-ring · Health Check (command) + +> Activate by typing `#qring-cmd-health-check` in chat. + +Run a comprehensive health check on all secrets — decay, anomalies, and audit integrity. + +## Workflow + +1. Call `health_check` to assess all secrets: + - Count healthy, stale (> 75% lifetime), and expired secrets + - Note any secrets without decay tracking +2. Call `detect_anomalies` to check for suspicious access patterns: + - Burst reads on a single key + - Access at unusual hours + - Access from new/unknown sources +3. Call `verify_audit_chain` to confirm the audit log has not been tampered with: + - Report total events and valid count + - If broken, show the break point +4. Present a summary report: + - Secrets: X healthy, Y stale, Z expired + - Anomalies: count and type + - Audit chain: intact or broken at event N + - Recommendations for any issues found diff --git a/kiro-plugin/steering/qring-cmd-rotate-expired.md b/kiro-plugin/steering/qring-cmd-rotate-expired.md new file mode 100644 index 0000000..35431fe --- /dev/null +++ b/kiro-plugin/steering/qring-cmd-rotate-expired.md @@ -0,0 +1,23 @@ +--- +inclusion: manual +--- + +# q-ring · Rotate Expired (command) + +> Activate by typing `#qring-cmd-rotate-expired` in chat. + +Find expired and stale secrets and attempt automatic rotation via their providers. + +## Workflow + +1. Call `health_check` to identify expired and stale secrets. +2. If no expired or stale secrets exist, report that everything is healthy. +3. For each expired secret: + - Call `validate_secret` to confirm it is actually invalid + - Call `rotate_secret` to attempt provider-native rotation + - Report the result: rotated (with provider name) or failed (with reason) +4. For stale secrets (> 75% lifetime), list them as warnings with remaining time. +5. Present a summary: + - **Rotated:** N secrets successfully refreshed + - **Failed:** N secrets could not be rotated (manual intervention needed) + - **Stale:** N secrets approaching expiry diff --git a/kiro-plugin/steering/qring-cmd-scan-secrets.md b/kiro-plugin/steering/qring-cmd-scan-secrets.md new file mode 100644 index 0000000..a42f6ad --- /dev/null +++ b/kiro-plugin/steering/qring-cmd-scan-secrets.md @@ -0,0 +1,22 @@ +--- +inclusion: manual +--- + +# q-ring · Scan Secrets (command) + +> Activate by typing `#qring-cmd-scan-secrets` in chat. + +Scan the current workspace for hardcoded secrets, API keys, and credentials. + +## Workflow + +1. Call `scan_codebase_for_secrets` with the current workspace root directory. +2. If no secrets are found, report that the codebase is clean. +3. If secrets are found, present them grouped by file: + - Show file path, line number, variable name, and entropy score + - Highlight high-entropy matches (> 4.0) as most likely real +4. Ask the user if they want to auto-fix: + - If yes, call `lint_files` with the affected files and `fix: true` + - This replaces hardcoded values with `process.env.KEY` references and stores the values in q-ring + - Report how many secrets were migrated +5. After fixing, re-run `scan_codebase_for_secrets` to confirm cleanup is complete. diff --git a/kiro-plugin/steering/qring-cmd-setup-project.md b/kiro-plugin/steering/qring-cmd-setup-project.md new file mode 100644 index 0000000..5bc1316 --- /dev/null +++ b/kiro-plugin/steering/qring-cmd-setup-project.md @@ -0,0 +1,33 @@ +--- +inclusion: manual +--- + +# q-ring · Setup Project (command) + +> Activate by typing `#qring-cmd-setup-project` in chat. + +Initialize q-ring for the current project — detect environment, create manifest, import `.env`, set up hooks. + +## Workflow + +1. Call `detect_environment` to determine the current environment context (dev, staging, prod). +2. Check if a `.q-ring.json` manifest already exists: + - If yes, call `check_project` to validate it and report missing or expired secrets + - If no, guide the user through creating one +3. Create a `.q-ring.json` manifest with: + - `env` and `defaultEnv` set to the detected environment + - `branchMap` mapping git branches to environments + - `secrets` declaring required credentials with descriptions and providers + - Optional `policy` section for governance +4. Check for existing `.env` files: + - If found, offer to import via `import_dotenv` with `skipExisting: true` + - Verify `.env` is in `.gitignore` +5. Call `env_generate` to produce a `.env` from the manifest. +6. Offer to register hooks via `register_hook`: + - Shell hooks for restarting services on credential changes + - HTTP hooks for deployment notifications +7. Summarize what was set up: + - Manifest location and declared secrets + - Imported secrets count + - Registered hooks + - Detected environment diff --git a/kiro-plugin/steering/qring-cmd-teleport-secrets.md b/kiro-plugin/steering/qring-cmd-teleport-secrets.md new file mode 100644 index 0000000..c21f259 --- /dev/null +++ b/kiro-plugin/steering/qring-cmd-teleport-secrets.md @@ -0,0 +1,36 @@ +--- +inclusion: manual +--- + +# q-ring · Teleport Secrets (command) + +> Activate by typing `#qring-cmd-teleport-secrets` in chat. + +Pack secrets into an encrypted bundle or unpack a received bundle for cross-machine transfer. + +## Workflow + +Ask the user whether they want to **pack** (send) or **unpack** (receive). + +### Pack (send secrets) + +1. Call `list_secrets` to show available secrets. +2. Ask the user which keys to include (or use tag-based selection). +3. Ask for a passphrase for encryption. +4. Call `teleport_pack` with the selected keys and passphrase. +5. Present the encrypted bundle string to the user for transfer (clipboard, secure channel, etc.). +6. Remind the user to share the passphrase through a separate channel. + +### Unpack (receive secrets) + +1. Ask the user to paste the encrypted bundle string. +2. Ask for the passphrase used during packing. +3. Call `teleport_unpack` with the bundle and passphrase. +4. Report the imported secrets: count, names, and scopes. +5. Offer to verify the imports with `list_secrets`. + +## Security notes + +- The bundle is AES-256-GCM encrypted — safe to transfer over untrusted channels. +- Always share the passphrase through a separate, secure channel (different from the bundle). +- Bundles are one-time use by convention — re-pack for additional transfers. diff --git a/kiro-plugin/steering/qring-env-file-safety.md b/kiro-plugin/steering/qring-env-file-safety.md new file mode 100644 index 0000000..bd0279b --- /dev/null +++ b/kiro-plugin/steering/qring-env-file-safety.md @@ -0,0 +1,16 @@ +--- +inclusion: fileMatch +fileMatchPattern: "**/.env*" +--- + +# q-ring · .env File Safety + +This steering activates whenever a `.env`, `.env.local`, `.env.production`, etc. file is in context. + +When a `.env` file is open or being edited: + +1. **Suggest importing.** Offer to call `import_dotenv` to migrate all key-value pairs into q-ring where they are encrypted in the OS keychain. +2. **Check `.gitignore`.** Verify that `.env*` patterns are in `.gitignore`. If not, warn the user immediately and offer to add them. +3. **Prefer manifest-driven generation.** If the project has a `.q-ring.json` manifest, suggest using `env_generate` to produce `.env` files on-demand from q-ring instead of maintaining them by hand. +4. **Never add new secrets** to `.env` files directly. Use `set_secret` (or `qring set KEY value`) and then `env_generate` to produce the file. +5. **Lint on save.** If the `qring-scan-on-save` agent hook is installed, the file will be automatically scanned. Otherwise, offer to call `lint_files` with the affected paths. diff --git a/kiro-plugin/steering/qring-exec-with-secrets.md b/kiro-plugin/steering/qring-exec-with-secrets.md new file mode 100644 index 0000000..7254576 --- /dev/null +++ b/kiro-plugin/steering/qring-exec-with-secrets.md @@ -0,0 +1,33 @@ +--- +inclusion: manual +--- + +# q-ring · Exec with Secrets (skill) + +> Activate by typing `#qring-exec-with-secrets` in chat. + +Run shell commands with secrets injected from q-ring — with stdout/stderr redaction and policy checks. + +## When to use + +- Running a project script that reads env vars you keep in q-ring +- One-off CLI tools (`curl`, SDK CLIs) that need a token from the keyring +- CI-like commands where redaction and `policy.exec` matter + +## Tool + +| Task | MCP tool | +|------|----------| +| Run command with env from q-ring | `exec_with_secrets` | + +## Workflow + +1. Call `get_policy_summary` if unsure whether `exec_with_secrets` is allowed (`policy.mcp` may deny this tool). +2. Prefer `check_policy` with `action: "exec"` when experimenting with deny/allow rules. +3. Call `exec_with_secrets` with the argv array, `projectPath`, and optional key filters so only required secrets are loaded. + +## Safety + +- Never log raw command output to public channels without reviewing redaction limits. +- Prefer `tunnel_create` / `tunnel_read` for one-off handoff of a single value to another agent when full `exec` is unnecessary. +- Use exec profiles (`restricted`, `ci`, `unrestricted`) to bound command behavior. diff --git a/kiro-plugin/steering/qring-project-onboarding.md b/kiro-plugin/steering/qring-project-onboarding.md new file mode 100644 index 0000000..ab29700 --- /dev/null +++ b/kiro-plugin/steering/qring-project-onboarding.md @@ -0,0 +1,90 @@ +--- +inclusion: manual +--- + +# q-ring · Project Onboarding (skill) + +> Activate by typing `#qring-project-onboarding` in chat. + +Set up q-ring for a new project — create manifests, detect environments, import secrets, configure hooks and policy. + +## When to use + +Activate when the user: +- Starts a new project and needs secret management +- Asks about `.q-ring.json` configuration +- Wants to detect or configure environments +- Needs to set up hooks for secret change notifications +- Asks about governance policy + +## Workflow + +### 1. Detect environment + +Call `detect_environment` to determine the current context. Sources checked in order: +1. Explicit `QRING_ENV` +2. `NODE_ENV` (mapped: `production` → `prod`, `development` → `dev`) +3. Git branch + `.q-ring.json` `branchMap` (supports globs like `release/*`) +4. `.q-ring.json` `defaultEnv` + +### 2. Check existing state + +Call `check_project` to validate against any existing `.q-ring.json` manifest. This reports: +- Required secrets that are present, missing, expired, or stale +- Overall project readiness + +### 3. Create or update the manifest + +Help the user create a `.q-ring.json` file with: + +```json +{ + "env": "dev", + "defaultEnv": "dev", + "branchMap": { + "main": "prod", + "develop": "dev", + "release/*": "staging" + }, + "secrets": { + "DATABASE_URL": { "required": true, "description": "PostgreSQL connection string" }, + "API_KEY": { "required": true, "provider": "openai", "description": "OpenAI API key" } + }, + "policy": { + "mcp": { "denyTools": ["exec_with_secrets"] }, + "secrets": { "maxTtlSeconds": 2592000 } + } +} +``` + +### 4. Import existing secrets + +If the project has `.env` files, offer to import them with `import_dotenv`. Use `skipExisting: true` to avoid overwriting. + +### 5. Generate `.env` from manifest + +Call `env_generate` to produce a `.env` file from the manifest with all declared secrets resolved from q-ring. + +### 6. Set up hooks + +Call `register_hook` to set up notifications when secrets change: +- Shell hook: restart dev server on DB credential change +- HTTP hook: notify a deployment webhook +- Signal hook: send SIGHUP to a running process + +Use `list_hooks` to inspect the registry and `remove_hook` to delete entries by id. (CLI-only: `qring hook enable|disable|test` for lifecycle control.) + +### 7. Configure policy + +Guide the user through the `policy` section of `.q-ring.json`: +- **mcp**: `allowTools` / `denyTools`, `readableKeys` / `deniedKeys`, `deniedTags` +- **exec**: `allowCommands` / `denyCommands`, `maxRuntimeSeconds`, `allowNetwork` +- **secrets**: `requireApprovalForTags`, `maxTtlSeconds` + +Call `get_policy_summary` to verify the policy is loaded correctly. + +## Best practices + +- Always create a `.q-ring.json` manifest for team projects — it serves as documentation and validation +- Use `branchMap` to automatically detect environments from git branches +- Set `required: true` on critical secrets so `check_project` catches missing credentials diff --git a/kiro-plugin/steering/qring-secret-hygiene.md b/kiro-plugin/steering/qring-secret-hygiene.md new file mode 100644 index 0000000..325a32f --- /dev/null +++ b/kiro-plugin/steering/qring-secret-hygiene.md @@ -0,0 +1,15 @@ +--- +inclusion: always +--- + +# q-ring · Secret Hygiene + +Enforce secret hygiene across this workspace — never hardcode credentials. + +- **Never** hardcode secrets, API keys, tokens, passwords, or connection strings in source code or config files. +- Store secrets using the `set_secret` MCP tool or `qring set` CLI — not in `.env` files, inline strings, or comments. +- Reference secrets in code via `process.env.KEY` (JS/TS), `os.environ["KEY"]` (Python), or the equivalent for the project language. The actual value lives in q-ring. +- When reviewing or writing code, flag any string that matches common credential patterns (`sk-*`, `ghp_*`, `Bearer *`, long base64 blobs, connection strings with passwords). +- If you spot a hardcoded secret, offer to run `scan_codebase_for_secrets` and `lint_files` with `fix: true` to migrate it into q-ring. +- Secrets with a TTL or rotation format should always be stored with `ttlSeconds` or `rotationFormat` so q-ring can track decay and automate rotation. +- When a shell command contains what looks like a secret value (long base64, `sk-*`, `ghp_*`, etc.), warn the user that secrets should not appear in shell history. Suggest `exec_with_secrets` instead. diff --git a/kiro-plugin/steering/qring-secret-management.md b/kiro-plugin/steering/qring-secret-management.md new file mode 100644 index 0000000..b067e92 --- /dev/null +++ b/kiro-plugin/steering/qring-secret-management.md @@ -0,0 +1,67 @@ +--- +inclusion: manual +--- + +# q-ring · Secret Management (skill) + +> Activate by typing `#qring-secret-management` in chat. + +Manage secrets stored in q-ring — store, retrieve, list, inspect, import, export, and configure superposition, decay, entanglement, and tags. + +## When to use + +Activate when the user: +- Asks to store, retrieve, delete, or list secrets +- Mentions API keys, tokens, passwords, credentials, or environment variables +- Wants to import from or export to `.env` files +- Needs superposition (per-environment values) or entanglement (linked secrets) +- Asks about secret expiry, TTL, tags, or access history + +## Workflow + +### 1. Understand the landscape + +Call `get_project_context` to get a redacted overview of existing secrets, scopes, manifest status, and recent activity. + +### 2. CRUD operations + +| Task | MCP Tool | +|------|----------| +| Store a secret | `set_secret` with optional `ttlSeconds`, `tags`, `description`, `env` (superposition), `rotationFormat` | +| Retrieve a secret | `get_secret` — collapses superposition automatically | +| Check existence | `has_secret` — never reveals the value | +| Delete a secret | `delete_secret` | +| List all secrets | `list_secrets` — filter with `tag`, `expired`, `stale`, `filter` | +| Inspect metadata | `inspect_secret` — shows decay, entanglement, access history (no value) | +| Usage / optimization | `analyze_secrets` — JSON report on secret usage patterns | + +`get_secret`, `list_secrets`, and related tools return **JSON** text payloads (not raw unwrapped strings) for predictable agent parsing. + +### 3. Import and export + +- **Import**: `import_dotenv` to bulk-load from `.env` content +- **Export**: `export_secrets` with format `env` or `json`, optional key/tag filters + +### 4. Superposition (multi-environment) + +Store per-environment values with the `env` parameter on `set_secret`: +- `set_secret(key="DB_URL", value="...", env="dev")` +- `set_secret(key="DB_URL", value="...", env="prod")` +- `get_secret` collapses to the detected environment automatically + +### 5. Entanglement + +Link secrets so rotating one updates the other: +- `entangle_secrets(sourceKey, targetKey)` — bidirectional link +- `disentangle_secrets(sourceKey, targetKey)` — remove link + +### 6. Scopes + +Secrets resolve through a cascade: project → team → org → global. Use the `scope` parameter to target a specific level. + +## Best practices + +- Always add a `description` when storing secrets for discoverability +- Use `tags` to group related secrets (e.g., `database`, `api`, `auth`) +- Set `ttlSeconds` for credentials that expire (forces rotation awareness) +- Use `generate_secret` to create high-entropy values instead of inventing them diff --git a/kiro-plugin/steering/qring-secret-ops.md b/kiro-plugin/steering/qring-secret-ops.md new file mode 100644 index 0000000..2824a80 --- /dev/null +++ b/kiro-plugin/steering/qring-secret-ops.md @@ -0,0 +1,51 @@ +--- +inclusion: manual +--- + +# q-ring · Secret Ops (agent persona) + +> Activate by typing `#qring-secret-ops` in chat. + +You are a hands-on secret operations assistant for q-ring. You help users manage their secrets through natural conversation. + +## Capabilities + +You have access to all q-ring MCP tools, with emphasis on: + +**Core CRUD** +- `get_secret`, `set_secret`, `delete_secret`, `has_secret`, `list_secrets` +- `inspect_secret` — view metadata without exposing values +- `generate_secret` — create high-entropy secrets in any format (hex, base64, uuid, api-key, token, password) + +**Ephemeral sharing** +- `tunnel_create` — create memory-only secrets with TTL and max-reads +- `tunnel_read`, `tunnel_list`, `tunnel_destroy` + +**Cross-machine transfer** +- `teleport_pack` — encrypt secrets into a portable bundle +- `teleport_unpack` — decrypt and import a bundle + +**Organization** +- `entangle_secrets` / `disentangle_secrets` — link secrets for coordinated rotation +- `agent_remember` / `agent_recall` / `agent_forget` — persist decisions across sessions + +**Environment** +- `detect_environment` — detect dev/staging/prod context +- `get_project_context` — understand the project's secret landscape + +## Behavior + +1. **Be conversational.** Help users think through what they need. Ask clarifying questions about scope (global vs project), environment, and TTL. +2. **Remember context.** Use `agent_remember` to store decisions like "this project uses OpenAI and Stripe" or "DB credentials rotate monthly". Use `agent_recall` to check past context before asking redundant questions. +3. **Suggest best practices:** + - Generate secrets with `generate_secret` instead of letting users invent them + - Add descriptions and tags for organization + - Set TTL for credentials that expire + - Use tunnels for one-time sharing instead of pasting values + - Use teleport for moving secrets between machines +4. **Be scope-aware.** When storing or retrieving secrets, consider whether the user needs global scope (shared across projects) or project scope (specific to the current workspace). +5. **Explain what happened.** After operations, confirm what was done: "Stored API_KEY in global scope with tag 'openai' and 90-day TTL." + +## Tone + +Be helpful and efficient. Explain q-ring concepts (superposition, entanglement, tunneling) in plain terms when users encounter them for the first time. diff --git a/kiro-plugin/steering/qring-secret-rotation.md b/kiro-plugin/steering/qring-secret-rotation.md new file mode 100644 index 0000000..da39645 --- /dev/null +++ b/kiro-plugin/steering/qring-secret-rotation.md @@ -0,0 +1,68 @@ +--- +inclusion: manual +--- + +# q-ring · Secret Rotation & Validation (skill) + +> Activate by typing `#qring-secret-rotation` in chat. + +Validate, rotate, and batch-check secrets against their providers. + +## When to use + +Activate when the user: +- Mentions expired, stale, or invalid secrets +- Asks to rotate or refresh API keys +- Wants to validate that secrets are still working +- Needs CI-friendly batch validation +- Asks about secret health or decay status + +## Workflow + +### 1. Health check + +Call `health_check` to get a full report of all secrets: +- **Expired** — TTL elapsed or `expiresAt` passed +- **Stale** — over 75% of lifetime consumed +- **Healthy** — within acceptable range +- Also returns anomaly count and overall status + +### 2. Validate individual secrets + +Call `validate_secret` with a key name. Supported providers with auto-detection: +- **OpenAI** — keys starting with `sk-` +- **Stripe** — keys starting with `sk_live_` or `sk_test_` +- **GitHub** — tokens starting with `ghp_`, `gho_`, `ghs_` +- **AWS** — keys starting with `AKIA` +- **Generic HTTP** — any URL-based validation endpoint + +Returns: `valid`, `invalid`, `error`, or `unknown` with latency and provider info. + +### 3. Rotate expired secrets + +Call `rotate_secret` with the key name. q-ring will: +- Attempt provider-native rotation if a provider is configured +- Fall back to local generation using the secret's `rotationFormat` and `rotationPrefix` +- Update the stored value and fire any registered hooks + +### 4. Batch CI validation + +Call `ci_validate_secrets` for a structured pass/fail report suitable for CI pipelines. Returns: +- Per-secret validation results +- Rotation recommendations +- Overall pass/fail status + +### 5. List available providers + +Call `list_providers` to see all supported validation providers with their prefix patterns and descriptions. + +### 6. Dashboard and autonomous scans + +- **`status_dashboard`** — starts the local quantum status dashboard (browser UI on localhost). +- **`agent_scan`** — one-shot health scan JSON (same family as CLI `qring agent --once`). + +## Best practices + +- Store secrets with `rotationFormat` (e.g., `api-key`, `password`, `uuid`) to enable automatic rotation +- Set `provider` metadata for automatic validation detection +- Run `ci_validate_secrets` in CI pipelines to catch expired credentials before deployment diff --git a/kiro-plugin/steering/qring-secret-scanning.md b/kiro-plugin/steering/qring-secret-scanning.md new file mode 100644 index 0000000..b6cf89a --- /dev/null +++ b/kiro-plugin/steering/qring-secret-scanning.md @@ -0,0 +1,56 @@ +--- +inclusion: manual +--- + +# q-ring · Secret Scanning (skill) + +> Activate by typing `#qring-secret-scanning` in chat. + +Scan and lint codebases for hardcoded secrets using entropy analysis and regex heuristics. + +## When to use + +Activate when the user: +- Asks to scan a project for hardcoded secrets or credentials +- Wants to audit code before a commit or PR +- Needs to migrate hardcoded values from source files into q-ring +- Mentions "secret leak", "credential scan", or "lint for secrets" + +## Workflow + +### 1. Scan the codebase + +Call `scan_codebase_for_secrets` with the project directory. The scanner uses: +- Regex heuristics matching common patterns (`api_key`, `secret`, `token`, `password`, etc.) +- Shannon entropy analysis (flags values with entropy > 3.5) +- Known prefix detection (`sk-`, `ghp_`, etc.) + +It automatically skips `node_modules`, `.git`, binary files, lockfiles, and minified code. + +### 2. Review findings + +Each result includes: +- `file` and `line` — location +- `keyName` — the detected variable name +- `match` — the suspicious value +- `entropy` — Shannon entropy score +- `context` — the full line of code + +Present findings grouped by file. Highlight high-entropy matches (> 4.0) as most likely to be real secrets. + +### 3. Auto-fix with lint + +Call `lint_files` with the list of affected files and `fix: true` to: +- Replace hardcoded values with `process.env.KEY` references (language-aware) +- Store the extracted values in q-ring automatically +- Support JS/TS, Python, Ruby, Go, Rust, Java, Kotlin, C#, PHP, and Shell + +### 4. Verify cleanup + +After fixing, re-run `scan_codebase_for_secrets` to confirm no secrets remain. + +## Best practices + +- Run scanning before every PR or commit +- Ignore placeholder values (`your_api_key`, `replace_me`, `example`) — the scanner handles this automatically +- For files with false positives, values under 8 characters or with low entropy are already filtered diff --git a/kiro-plugin/steering/qring-security-auditor.md b/kiro-plugin/steering/qring-security-auditor.md new file mode 100644 index 0000000..130a6e3 --- /dev/null +++ b/kiro-plugin/steering/qring-security-auditor.md @@ -0,0 +1,42 @@ +--- +inclusion: manual +--- + +# q-ring · Security Auditor (agent persona) + +> Activate by typing `#qring-security-auditor` in chat. + +You are a security-focused agent for q-ring. Your job is to proactively monitor the health and integrity of the project's secret management. + +## Capabilities + +You have access to these q-ring MCP tools: + +- `health_check` — assess decay, staleness, and anomalies across all secrets +- `audit_log` — query the tamper-evident audit trail (filter by key, action, source, time) +- `verify_audit_chain` — verify the SHA-256 hash chain has not been tampered with +- `detect_anomalies` — flag burst reads, unusual-hour access, new sources, and tampering +- `scan_codebase_for_secrets` — scan the project for hardcoded credentials +- `check_policy` — verify an action is allowed by governance policy +- `get_policy_summary` — show the full policy configuration +- `export_audit` — export audit events as JSONL, JSON, or CSV + +## Behavior + +1. **Start with a health check.** Call `health_check` to get the overall status. Report expired, stale, and healthy counts. +2. **Verify audit integrity.** Call `verify_audit_chain` to confirm the hash chain is intact. If broken, report the break point and affected event. +3. **Detect anomalies.** Call `detect_anomalies` to find suspicious patterns: + - **Burst reads** — many reads of the same key in a short window + - **Unusual-hour access** — reads outside normal working hours + - **New source** — access from a previously unseen source + - **Tampering** — audit entries with invalid hashes +4. **Scan for leaks.** Call `scan_codebase_for_secrets` on the project directory and report any hardcoded credentials found. +5. **Check governance.** If a `.q-ring.json` policy exists, call `get_policy_summary` and verify that denied tools, keys, and tags are properly configured. +6. **Generate a report.** Summarize findings with counts and severity levels: + - **Critical:** tampered audit chain, hardcoded secrets, expired credentials + - **Warning:** stale secrets, anomalous access patterns + - **Info:** healthy secret counts, policy status + +## Tone + +Be direct and factual. Present findings as a structured report. Recommend specific remediation actions for each issue found. diff --git a/kiro-plugin/steering/qring-workflow.md b/kiro-plugin/steering/qring-workflow.md new file mode 100644 index 0000000..8eccca3 --- /dev/null +++ b/kiro-plugin/steering/qring-workflow.md @@ -0,0 +1,15 @@ +--- +inclusion: always +--- + +# q-ring · Workflow + +Use q-ring MCP tools for **all** secret operations — never access the OS keychain directly. + +- Use q-ring MCP tools (`get_secret`, `set_secret`, `list_secrets`, etc.) for every secret operation. Never call OS keychain APIs directly. +- Before working with a project's secrets for the first time, call `get_project_context` to understand what secrets exist, their scopes, and any governance policy. +- If the project has a `.q-ring.json` file, call `check_policy` before performing tool or exec actions to respect governance rules. +- After writing or deleting a secret, remind the user that q-ring maintains a tamper-evident audit trail accessible via `audit_log`. +- For ephemeral values (one-time tokens, OTPs), use `tunnel_create` instead of `set_secret` — tunnels are memory-only and self-destruct after a TTL or read count. +- For sharing secrets across machines, use `teleport_pack` / `teleport_unpack` — never paste raw credentials into chat or files. +- Treat the q-ring MCP server (`q-ring`) as the single source of truth for secret values. Treat `.env` files as derived artifacts produced by `env_generate`. diff --git a/package.json b/package.json index 4bc4c89..141307d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@i4ctime/q-ring", - "version": "0.11.0", + "version": "0.11.5", "mcpName": "io.github.I4cTime/q-ring", "description": "Quantum keyring for AI coding tools — Cursor, Kiro, Claude Code. Secrets, superposition, entanglement, MCP.", "type": "module", @@ -25,6 +25,8 @@ "test:ci": "vitest run", "sync-versions": "node scripts/sync-versions.mjs", "plugin:sync": "node scripts/plugin-sync.mjs", + "plugin:sync:kiro": "node scripts/plugin-sync-kiro.mjs", + "plugin:sync:claude": "node scripts/plugin-sync-claude.mjs", "docs:publish-log": "node scripts/append-changelog-to-publish-log.mjs", "prepublishOnly": "pnpm run build && pnpm run sync-versions" }, @@ -48,7 +50,7 @@ "bugs": { "url": "https://github.com/I4cTime/quantum_ring/issues" }, - "homepage": "https://i4ctime.github.io/quantum_ring/", + "homepage": "https://qring.i4c.studio", "dependencies": { "@modelcontextprotocol/sdk": "^1.27.1", "@napi-rs/keyring": "^1.2.0", diff --git a/scripts/plugin-sync-claude.mjs b/scripts/plugin-sync-claude.mjs new file mode 100644 index 0000000..60b0500 --- /dev/null +++ b/scripts/plugin-sync-claude.mjs @@ -0,0 +1,131 @@ +#!/usr/bin/env node +/** + * Copy `claude-code-plugin/` into a Claude Code project (or ~/.claude for the + * user-level extensions). + * + * # Default — install into $PWD as a project-scoped plugin + * node scripts/plugin-sync-claude.mjs + * + * # Install into a specific project + * node scripts/plugin-sync-claude.mjs /path/to/your/project + * + * # Install agents/commands/skills/hooks at user scope + * # (CLAUDE.md and .mcp.json are NOT copied to the home dir) + * node scripts/plugin-sync-claude.mjs --user + * + * # Force overwrite of existing settings.json, .mcp.json, CLAUDE.md + * node scripts/plugin-sync-claude.mjs --force + * + * Project-scoped layout: + * claude-code-plugin/CLAUDE.md -> $DEST/CLAUDE.md + * claude-code-plugin/.mcp.json -> $DEST/.mcp.json + * claude-code-plugin/.claude/agents/* -> $DEST/.claude/agents/ + * claude-code-plugin/.claude/commands/* -> $DEST/.claude/commands/ + * claude-code-plugin/.claude/skills/* -> $DEST/.claude/skills/ + * claude-code-plugin/.claude/hooks/* -> $DEST/.claude/hooks/ + * claude-code-plugin/.claude/settings.json -> $DEST/.claude/settings.json + * + * Files inside agents/, commands/, skills/, and hooks/ are namespaced (qring-*, + * secret-ops, etc.) so they do not collide with user files. They are always + * overwritten. + * + * `settings.json`, `.mcp.json`, and `CLAUDE.md` may already be customized by + * the user. By default, when one of those files already exists at the + * destination, this script writes `.qring-template` next to it and + * leaves the original alone. Pass `--force` to overwrite anyway. + */ +import { + cpSync, + mkdirSync, + existsSync, + readdirSync, + statSync, + copyFileSync, +} from "node:fs"; +import { dirname, join } from "node:path"; +import { homedir } from "node:os"; +import { fileURLToPath } from "node:url"; + +const root = join(dirname(fileURLToPath(import.meta.url)), ".."); +const src = join(root, "claude-code-plugin"); + +if (!existsSync(src)) { + console.error(`plugin-sync-claude: missing source directory ${src}`); + process.exit(1); +} + +const args = process.argv.slice(2); +const userScope = args.includes("--user"); +const force = args.includes("--force"); +const positional = args.filter((a) => !a.startsWith("--")); +const projectDest = positional[0] ?? process.cwd(); +const dest = userScope ? homedir() : projectDest; + +const claudeSrc = join(src, ".claude"); +const claudeDest = join(dest, ".claude"); + +let copiedFiles = 0; +const skipped = []; + +const writeOrTemplate = (from, to) => { + if (existsSync(to) && !force) { + const tpl = `${to}.qring-template`; + copyFileSync(from, tpl); + skipped.push({ to, tpl }); + copiedFiles += 1; + return; + } + mkdirSync(dirname(to), { recursive: true }); + copyFileSync(from, to); + copiedFiles += 1; +}; + +const subdirs = ["agents", "commands", "skills", "hooks"]; +for (const sub of subdirs) { + const srcDir = join(claudeSrc, sub); + if (!existsSync(srcDir) || !statSync(srcDir).isDirectory()) continue; + const destDir = join(claudeDest, sub); + mkdirSync(destDir, { recursive: true }); + for (const entry of readdirSync(srcDir)) { + if (entry.startsWith(".")) continue; + const from = join(srcDir, entry); + const to = join(destDir, entry); + cpSync(from, to, { recursive: true }); + copiedFiles += 1; + } +} + +const settingsSrc = join(claudeSrc, "settings.json"); +if (existsSync(settingsSrc)) { + writeOrTemplate(settingsSrc, join(claudeDest, "settings.json")); +} + +if (!userScope) { + const claudeMd = join(src, "CLAUDE.md"); + const mcpJson = join(src, ".mcp.json"); + if (existsSync(claudeMd)) writeOrTemplate(claudeMd, join(dest, "CLAUDE.md")); + if (existsSync(mcpJson)) writeOrTemplate(mcpJson, join(dest, ".mcp.json")); +} + +const scope = userScope ? "user (~/.claude)" : `project (${projectDest})`; +console.log( + `plugin-sync-claude: copied ${copiedFiles} entr${copiedFiles === 1 ? "y" : "ies"} into ${scope}`, +); + +if (skipped.length > 0) { + console.log(""); + console.log( + "The following files already existed and were NOT overwritten. Saved a side-by-side template instead — review and merge by hand, or rerun with --force to overwrite:", + ); + for (const { to, tpl } of skipped) { + console.log(` ${to}`); + console.log(` -> template: ${tpl}`); + } +} + +if (!userScope) { + console.log(""); + console.log( + "First time you run `claude` in this project, approve the project-scoped MCP server defined in `.mcp.json`.", + ); +} diff --git a/scripts/plugin-sync-kiro.mjs b/scripts/plugin-sync-kiro.mjs new file mode 100644 index 0000000..92effe6 --- /dev/null +++ b/scripts/plugin-sync-kiro.mjs @@ -0,0 +1,101 @@ +#!/usr/bin/env node +/** + * Copy `kiro-plugin/` into a Kiro `.kiro/` config tree. + * + * Default destination: `~/.kiro` (user-level — applies to every Kiro project). + * Pass an explicit destination as the first arg to install at project scope: + * + * node scripts/plugin-sync-kiro.mjs /path/to/your/project/.kiro + * + * The destination is treated as a `.kiro` directory: this script copies + * kiro-plugin/mcp.json (Power root) -> $DEST/settings/mcp.json (safe — see below) + * kiro-plugin/steering/* -> $DEST/steering/ (namespaced files) + * kiro-plugin/hooks/* -> $DEST/hooks/ (namespaced files) + * + * Steering and hook files are namespaced (`qring-*`) so they do not collide + * with user files. They are always overwritten. + * + * `settings/mcp.json` at the destination may already be customized by the user with other MCP + * servers. By default, when that file already exists at the destination, this + * script writes `mcp.json.qring-template` next to it and leaves the original + * alone. Pass `--force` to overwrite anyway. + */ +import { + cpSync, + mkdirSync, + existsSync, + readdirSync, + statSync, + copyFileSync, +} from "node:fs"; +import { dirname, join } from "node:path"; +import { homedir } from "node:os"; +import { fileURLToPath } from "node:url"; + +const root = join(dirname(fileURLToPath(import.meta.url)), ".."); +const src = join(root, "kiro-plugin"); + +const args = process.argv.slice(2); +const force = args.includes("--force"); +const positional = args.filter((a) => !a.startsWith("--")); +const dest = positional[0] ?? join(homedir(), ".kiro"); + +if (!existsSync(src)) { + console.error(`plugin-sync-kiro: missing source directory ${src}`); + process.exit(1); +} + +let copiedFiles = 0; +const skipped = []; + +const writeOrTemplate = (from, to) => { + if (existsSync(to) && !force) { + const tpl = `${to}.qring-template`; + copyFileSync(from, tpl); + skipped.push({ to, tpl }); + copiedFiles += 1; + return; + } + mkdirSync(dirname(to), { recursive: true }); + copyFileSync(from, to); + copiedFiles += 1; +}; + +const mcpSrc = join(src, "mcp.json"); +if (existsSync(mcpSrc)) { + writeOrTemplate(mcpSrc, join(dest, "settings", "mcp.json")); +} + +for (const sub of ["steering", "hooks"]) { + const srcDir = join(src, sub); + if (!existsSync(srcDir) || !statSync(srcDir).isDirectory()) continue; + const destDir = join(dest, sub); + mkdirSync(destDir, { recursive: true }); + for (const entry of readdirSync(srcDir)) { + if (entry.startsWith(".")) continue; + const from = join(srcDir, entry); + const to = join(destDir, entry); + cpSync(from, to, { recursive: true }); + copiedFiles += 1; + } +} + +console.log( + `plugin-sync-kiro: copied ${copiedFiles} entr${copiedFiles === 1 ? "y" : "ies"} from ${src} -> ${dest}`, +); + +if (skipped.length > 0) { + console.log(""); + console.log( + "The following files already existed and were NOT overwritten. Saved a side-by-side template instead — review and merge by hand, or rerun with --force to overwrite:", + ); + for (const { to, tpl } of skipped) { + console.log(` ${to}`); + console.log(` -> template: ${tpl}`); + } +} + +console.log(""); +console.log( + "Reload Kiro's MCP servers from the MCP Servers panel to pick up the new q-ring config.", +); diff --git a/server.json b/server.json index a0655bd..cbf8314 100644 --- a/server.json +++ b/server.json @@ -6,12 +6,12 @@ "url": "https://github.com/I4cTime/quantum_ring", "source": "github" }, - "version": "0.11.0", + "version": "0.11.5", "packages": [ { "registryType": "npm", "identifier": "@i4ctime/q-ring", - "version": "0.11.0", + "version": "0.11.5", "transport": { "type": "stdio" } diff --git a/src/mcp/tools/audit.ts b/src/mcp/tools/audit.ts index 91c946e..ebd06d8 100644 --- a/src/mcp/tools/audit.ts +++ b/src/mcp/tools/audit.ts @@ -61,7 +61,7 @@ export function registerAuditTools(server: McpServer): void { server.tool( "detect_anomalies", - "[audit] Scan for anomalous secret access patterns: burst reads, unusual-hour access. Returns findings and recommendations.", + "[audit] Read-only scan of audit history for burst reads and unusual-hour access (text lines per finding). Optional key filter. Use health_check for full decay inventory + anomaly count in scope; use agent_scan for multi-project JSON reports or optional auto-rotation. Does not mutate secrets.", { key: z.string().optional().describe("Check anomalies for a specific key"), }, @@ -79,7 +79,7 @@ export function registerAuditTools(server: McpServer): void { server.tool( "health_check", - "[health] Run a comprehensive health check on all secrets: decay status, staleness, anomalies, entropy assessment.", + "[health] Read-only scoped pass: decay/stale/expired counts, per-secret issue lines, plus audit-derived anomalies. No writes. Use check_project for .q-ring.json manifest compliance; use detect_anomalies for audit-pattern-only triage; use agent_scan for multi-project JSON or optional autoRotate credential replacement.", { scope, projectPath, diff --git a/src/mcp/tools/hooks.ts b/src/mcp/tools/hooks.ts index eb3c3ac..dd331f1 100644 --- a/src/mcp/tools/hooks.ts +++ b/src/mcp/tools/hooks.ts @@ -95,7 +95,7 @@ export function registerHookTools(server: McpServer): void { server.tool( "remove_hook", - "[hooks] Remove a registered hook by ID.", + "[hooks] Remove a lifecycle hook entry by id from the hook registry only (stops callbacks; does not touch secret values). Call list_hooks first for ids. Contrast delete_secret (credential removal) or tunnel_destroy (ephemeral tunnel). Returns success or not-found; subject to tool policy.", { id: z.string().describe("Hook ID to remove"), }, diff --git a/src/mcp/tools/secrets.ts b/src/mcp/tools/secrets.ts index 43ee766..7ce2e13 100644 --- a/src/mcp/tools/secrets.ts +++ b/src/mcp/tools/secrets.ts @@ -123,7 +123,7 @@ export function registerSecretTools(server: McpServer): void { server.tool( "set_secret", - "[secrets] Store a secret with optional quantum metadata: TTL (decay), environment state (superposition), description, tags.", + "[secrets] Create or overwrite a secret value plus optional metadata (TTL/decay, per-env superposition, description, tags). Overwrites existing values for the same key/scope; records access in the audit log. Use import_dotenv for bulk .env ingest. Subject to tool policy; no external rate limits beyond provider calls when validating elsewhere.", { key: z.string().describe("The secret key name"), value: z.string().describe("The secret value"), @@ -206,7 +206,7 @@ export function registerSecretTools(server: McpServer): void { server.tool( "delete_secret", - "[secrets] Remove a secret from the keyring.", + "[secrets] Permanently remove a secret value from the keyring for the given scope/path (not recoverable from q-ring). Does not remove hooks, tunnels, or entanglement metadata alone—use remove_hook, tunnel_destroy, or disentangle_secrets respectively. Returns success or not-found text; subject to tool policy.", { key: z.string().describe("The secret key name"), scope, @@ -441,7 +441,7 @@ export function registerSecretTools(server: McpServer): void { server.tool( "entangle_secrets", - "[secrets] Create a quantum entanglement between two secrets. When the source is rotated/updated, the target automatically receives the same value.", + "[secrets] Link two keys so source updates/rotations propagate the same value to the target (mutates metadata; future writes sync). Reverse with disentangle_secrets without deleting values; do not confuse with set_secret (single-key write). Subject to tool policy.", { sourceKey: z.string().describe("Source secret key"), targetKey: z.string().describe("Target secret key"), @@ -478,7 +478,7 @@ export function registerSecretTools(server: McpServer): void { server.tool( "disentangle_secrets", - "[secrets] Remove a quantum entanglement between two secrets. They will no longer synchronize on rotation.", + "[secrets] Remove the sync link between two keys so rotations stop propagating. Does not delete either secret—use delete_secret to erase values. Contrast entangle_secrets (creates link). Safe if the link was already absent; updates metadata; subject to tool policy.", { sourceKey: z.string().describe("Source secret key"), targetKey: z.string().describe("Target secret key"), diff --git a/src/mcp/tools/tooling.ts b/src/mcp/tools/tooling.ts index 0ac4435..903bcf7 100644 --- a/src/mcp/tools/tooling.ts +++ b/src/mcp/tools/tooling.ts @@ -214,7 +214,7 @@ export function registerToolingTools(server: McpServer): void { server.tool( "agent_scan", - "[agent] Run an autonomous agent health scan: checks decay, staleness, anomalies, and optionally auto-rotates expired secrets. Returns a structured report.", + "[agent] Multi-project health pass: decay, staleness, audit anomalies, manifest gaps; returns JSON. Prefer health_check for a read-only scoped decay/anomaly text summary (no writes). Prefer detect_anomalies for audit-pattern spikes on one key. With autoRotate=true, overwrites expired secret values in the keyring (credential change—not undoable); leave false unless intentional rotation. Same policy gates as other MCP tools; no separate external auth.", { autoRotate: z .boolean() diff --git a/web/.gitignore b/web/.gitignore deleted file mode 100644 index 5ef6a52..0000000 --- a/web/.gitignore +++ /dev/null @@ -1,41 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.* -.yarn/* -!.yarn/patches -!.yarn/plugins -!.yarn/releases -!.yarn/versions - -# testing -/coverage - -# next.js -/.next/ -/out/ - -# production -/build - -# misc -.DS_Store -*.pem - -# debug -npm-debug.log* -yarn-debug.log* -yarn-error.log* -.pnpm-debug.log* - -# env files (can opt-in for committing if needed) -.env* - -# vercel -.vercel - -# typescript -*.tsbuildinfo -next-env.d.ts diff --git a/web/app/changelog/page.tsx b/web/app/changelog/page.tsx deleted file mode 100644 index 9b310fc..0000000 --- a/web/app/changelog/page.tsx +++ /dev/null @@ -1,89 +0,0 @@ -import type { Metadata } from "next"; -import Link from "next/link"; -import { Breadcrumbs, Chip } from "@heroui/react"; -import { ChevronLeft, ScrollText } from "lucide-react"; - -import Nav from "@/components/Nav"; -import Footer from "@/components/Footer"; -import FadeIn from "@/components/motion/FadeIn"; -import ChangelogList from "@/components/changelog/ChangelogList"; -import { CHANGELOG, CHANGELOG_RELEASE_COUNT } from "@/lib/data/changelog"; - -export const metadata: Metadata = { - title: "Changelog — q-ring", - description: "Version history and release notes for q-ring.", -}; - -export default function ChangelogPage() { - const latest = CHANGELOG[0]; - return ( - <> -