Skip to content

WeLikeCode/mintkey

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

888 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Mintkey

A self-hostable broker that lets autonomous agents discover services, acquire scoped short-lived credentials for them, and call them through a proxy that the real credentials never leave through — with operator-grade observability and per-request audit.

docs/architecture/00-vision/02-product-vision.md

Status: pre-alpha. The wire surface is declared experimental (docs/architecture/contracts/rest/openapi.yaml x-mintkey-stability). Breaking changes will bump the major version. Do not use this in production.


Status

Item State
Milestones WS-0 → WS-8 complete (Phase 1); v0.1.0-prealpha tagged 2026-05-17
Unit tests 244 passing (2026-05-12 WS-8 snapshot)
Architecture tests 17 passing (2026-05-12 WS-8 snapshot)
Go package tests 23 packages green (2026-05-12 WS-8 snapshot)
Wire surface stability experimental (openapi.yaml v0.1.0-preview.1)
License Apache-2.0

See PROGRESS.md for the full milestone checklist.


What this is / what this is not

Is:

  • A credential broker for AI agents: register services, store credentials encrypted, grant agents scoped access.
  • An egress proxy (Kong + Go plugin) that injects the real credential in-flight — the agent never holds it.
  • An SSH bastion on :2222 that multiplexes agent SSH sessions to any registered upstream host via a single listener, dispatching by JWT claim — no custom client needed, no per-service ports (architecture, ADR-0022).
  • An MCP server: agents discover services and request JWTs without out-of-band setup.
  • Per-request audit with a mandatory hash chain (ADR-0014.7).
  • Self-hostable via docker compose up.

Is not:

  • A general-purpose secrets manager for humans and CI/CD pipelines.
  • An agent runtime or orchestrator.
  • An inbound API gateway.
  • A prompt-injection prevention layer (it contains blast radius; it does not prevent injection).
  • Multi-region or horizontally scaled out of the box.

See docs/architecture/00-vision/02-product-vision.md for the full non-goals list.


At a glance

sequenceDiagram
    participant A as Agent
    participant M as MCP Server
    participant B as Credential Broker
    participant P as Egress Proxy (Kong)
    participant S as Backend Service

    A->>M: list_services (MCP)
    M-->>A: service catalog (svc_... ULIDs)
    A->>M: request_token(service_id, scope)
    M->>B: issue JWT
    B-->>M: JWS Ed25519 JWT (TTL 10m)
    M-->>A: JWT
    A->>P: GET /api/... (Authorization: Bearer JWT)
    P->>B: validate JWT
    B-->>P: valid -- credential ref
    P->>P: inject real credential (per-request only)
    P->>S: GET /api/... (real credential)
    S-->>P: response
    P-->>A: response (credential stripped)
Loading

The agent never touches the underlying credential. Full sequence: docs/architecture/03-flows/E2E-01-builder-happy-path.md.


Run it locally (5 minutes)

git clone https://github.com/WeLikeCode/mintkey.git mintkey
cd mintkey
docker compose up -d
make smoke

On a clean machine, the 17 long-running containers and 2 one-shot jobs (liquibase, seed-job) reach healthy state within ≤ 120 seconds. make smoke runs the E2E-01 happy path and completes within ≤ 90 seconds.

Expected docker compose ps output: 17 services showing Up (healthy), 2 one-shot jobs showing Exit 0.

Get the bootstrap admin password:

docker run --rm -v mintkey_bootstrap_secrets:/secrets alpine \
  cat /secrets/admin_password

Admin UI: http://localhost:8081 — full port map in PORTS.md.

Log in at http://localhost:8081 — click Sign in with Keycloak and paste the password above. Full auth reference: docs/AUTH.md.

Full walkthrough: docs/guides/github-quickstart.md.

Vault storage backend

Vault storage backend: encrypted credentials stored in the vault.credentials table in the main mintkey Postgres DB by default. Selectable via MINTKEY_VAULT_BACKEND={postgres|sqlite}; SQLite fallback at MINTKEY_VAULT_FILE_PATH for offline/embedded deploys. See ADR-0021 and docs/HOW-TO.md §5 for migration.

Backup local state before a reset

Local docker volumes hold curated state (agents/services in postgres_data, vault credentials in vault_data/vault_kek, bootstrap secrets). docker compose down -v wipes all 7 named volumes permanently (EV-DESTRUCTIVE-001, EV-VOL-001..007). Before any reset:

bash scripts/dev-backup.sh

Default mode redacts secrets and writes to .mintkey-backups/<timestamp>/. To recover later:

bash scripts/dev-restore.sh .mintkey-backups/<timestamp> --dry-run   # see what would change
bash scripts/dev-restore.sh .mintkey-backups/<timestamp> --apply     # actually restore

Full workflow: docs/operations/backup-before-reset.md. EvidenceRefs (source of truth): see that doc's appendix.


Where to read next

Goal Start here
Run the demo docs/guides/github-quickstart.md
Understand the architecture docs/architecture/README.md
Deploy on a LAN or behind a reverse proxy docs/NETWORK.md — env-var setup for MINTKEY_MCP_PUBLIC_URL / MINTKEY_PROXY_PUBLIC_URL
Operator auth, SSO, break-glass docs/AUTH.md
Contribute code CONTRIBUTING.md, then docs/SDD.md
Debug a running stack docs/DEBUG.md
Report a bug or security issue docs/REPORTING.md / SECURITY.md
Read the marketing summary marketing/index.html

Repo map

README.md                          this file
CONTRIBUTING.md                    contribution gate (SDD zero tolerance)
SECURITY.md                        vulnerability disclosure policy
CLAUDE.md                          Claude Code instructions (authoritative)
AGENTS.md                          coding-agent instructions (lock-step sibling)
QUICKSTART.md                      local setup (steps, ports, smoke test)
PORTS.md                           port map + service list
PROGRESS.md                        milestone checklist + test counts
BOOTSTRAP.md                       bootstrap notes
apps/
  admin-api/                       Admin REST API — Python + FastAPI
  admin-ui/                        Admin Console — AdminJS (TypeScript)
  mcp-server/                      MCP Server — Python + FastAPI
  mock-backend/                    Demo backend (all auth schemes)
  seed-job/                        One-shot bootstrap job
  audit-verify-job/                Scheduled audit chain verification
  broker/                          Credential Broker — EdDSA JWT issuer (Go)
  vault-adapter/                   Vault Adapter — credential store (Go); default backend: Postgres (`vault.credentials`)
  kong-syncer/                     Kong declarative YAML pusher (Go)
  proxy-plugin/                    Kong go-pdk egress plugin (Go)
  jaeger-auth/                     Jaeger OIDC auth proxy
packages/
  python/mintkey-models/           Shared Python package (Pydantic v2 + SQLAlchemy Mapped)
  go/audit/                        Go audit emission helper
  go/auditq/                       Go audit queue
  go/changes/                      Postgres LISTEN/NOTIFY client
  go/otelinit/                     OTel SDK bootstrap
  go/svcid/                        Service identity boot-secret client
  go/ulid/                         ULID helpers
  go/vault/                        Vault proto + Go stubs
infra/
  compose/                         docker-compose.yml (primary), docker-compose.test.yml
  observability/                   prometheus.yml, alert_rules.yml, otel-collector-config.yaml, grafana/
  keycloak/                        Keycloak realm placeholders
docker-compose.yml                 Root shim (includes infra/compose/docker-compose.yml)
docs/
  architecture/                    SOURCE OF TRUTH for architectural design
    README.md                      reading order
    00-vision/                     problem, vision, personas, roadmap
    01-architecture/
      adr/                         20 ADRs (all accepted; ADR-0018 accepted 2026-05-11, ADR-0020 accepted 2026-05-15)
      open-questions.md            22 OQ-* tracked items
    03-flows/                      E2E-01 + 6 component flows
    contracts/                     REST OpenAPI, MCP tools, event schemas, proto
    proposal/                      9 accepted proposals
  guides/
    github-quickstart.md           operator runbook (GitHub PAT example)
    hermes-coingecko-quickstart.md operator runbook (CoinGecko example)
  SDD.md                           Spec-Driven Development explainer
  HOW-TO.md                        operator playbook index
  DEBUG.md                         layered troubleshooting
  REPORTING.md                     bug / feature / feedback routing
remediation/
  active/                          Ongoing remediation sessions
  archive/2026/05/                 44 completed sessions (historical; read-only)
  SESSION_TEMPLATE/                Scaffold for new sessions
.kiro/
  specs/mintkey-mvp/               Phase 1: requirements, design, tasks (M1.0-M1.13)
  steering/                        project-wide steering rules
marketing/
  index.html                       landing page
  architecture.html                architecture deep dive
  security.html                    security posture

Project rules in 60 seconds

  1. Spec-Driven Development is mandatory. No code without a spec entry under .kiro/specs/. See CONTRIBUTING.md (zero tolerance section) and docs/SDD.md.
  2. Architecture lives in ADRs; ADRs are immutable once Accepted. To change a decision, write a new ADR that supersedes the old. See docs/architecture/01-architecture/adr/0001-record-architecture-decisions.md.
  3. The OpenAPI YAML is canonical; CI diffs against it. Any handler that does not match docs/architecture/contracts/rest/openapi.yaml fails the build. See CLAUDE.md "Architecture immutability".
  4. The plaintext credential never appears in any log, audit payload, OTel span attribute, or response visible to the agent. Scenario S-SEC-1; see ADR-0014.4 and ADR-0017.6.
  5. Validate with tools, never with hallucinations. A claim without a tool output is a hypothesis. See CLAUDE.md Principle 1.

Full guardrails: CLAUDE.md and AGENTS.md (kept in lock-step).


Install

Clone-free (operator path — Docker only)

Post-merge path (default). The install.sh, docker-compose.ghcr.yml, and config tree in this section only exist on main after this branch is merged. Running the one-liner against main before the merge returns a 404.

# Create a directory and run the installer:
mkdir mintkey && cd mintkey
curl -fsSL https://raw.githubusercontent.com/WeLikeCode/mintkey/main/install.sh | bash

Pre-merge / branch testing. To test from this branch before it lands on main, set MINTKEY_BRANCH so the installer fetches files from the feature branch:

mkdir mintkey && cd mintkey
MINTKEY_BRANCH=feat/ghcr-compose-and-install \
  curl -fsSL https://raw.githubusercontent.com/WeLikeCode/mintkey/feat/ghcr-compose-and-install/install.sh | bash

The script downloads docker-compose.ghcr.yml and all required config files, generates a Fernet KEK, writes a starter .env, pulls images from GHCR, and starts the stack. No git clone needed.

Ports used: 8080 (admin-api), 8081 (admin-ui), 8082 (mcp-server), 8083 (broker), 8084/8087 (vault-adapter), 8085 (kong-syncer), 8086 (proxy-plugin), 8000 (kong), 8443 (keycloak), 3003 (grafana), 16686 (jaeger), 4317 (otel-collector), 8999 (mock-backend).

To target a specific release tag:

MINTKEY_BRANCH=v1.2.3 bash install.sh

After the stack comes up, retrieve the bootstrap admin password:

MINTKEY_BOOTSTRAP_KEK=$(grep MINTKEY_BOOTSTRAP_KEK .env | cut -d= -f2-)
python3 -c "
import os
from cryptography.fernet import Fernet
with open('data/bootstrap-secrets/admin_password','rb') as f:
    print(Fernet(os.environ['MINTKEY_BOOTSTRAP_KEK'].encode()).decrypt(f.read().strip()).decode())
"

Keep .env safe — losing MINTKEY_BOOTSTRAP_KEK makes the bootstrap admin password unrecoverable without a full reset (docker compose down -v).

Multi-arch note

GHCR images are built by publish.yml. The multi-arch change (linux/amd64 + linux/arm64) in this branch only takes effect after this PR merges and publish.yml re-runs. Until that re-publish completes, ARM hosts (linux/arm64/v8) will see no matching manifest when pulling images.

To verify both architectures are present after merge:

docker manifest inspect ghcr.io/welikecode/mintkey-admin-api:latest
# Both linux/amd64 and linux/arm64 entries should appear in the manifests list.

If you are on an ARM host and see the manifest error before the post-merge re-publish completes, wait for the publish.yml workflow run to finish on main and then retry.

Developer path (requires git clone)

git clone https://github.com/WeLikeCode/mintkey.git && cd mintkey
bash scripts/dev-install.sh   # full automated setup with --clean / --force-destroy guards
# or, to bring up the stack manually:
docker compose -f infra/compose/docker-compose.yml up -d

scripts/dev-install.sh is the original developer install script (moved from the repo root). It handles --clean, --force-destroy, interactive prompts, --non-interactive mode, SIGINT/SIGTERM cleanup, and .env generation automatically.


Stability and versioning

Mintkey is pre-alpha. The wire surface is declared experimental in docs/architecture/contracts/rest/openapi.yaml (x-mintkey-stability: experimental, version 0.1.0-preview.1). Breaking changes will bump the major version; resource-level stability is called out per operation in the OpenAPI description where it differs from the document tier.

There is no managed offering. Self-host only.


License

Apache-2.0. See docs/architecture/contracts/rest/openapi.yaml info.license.

About

The agentic first secrets vault

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors