consciousness-key-server v1.0.0 AGPL-3.0-only + Commercial

Consciousness Key Server

A secrets vault without the HashiCorp weight.

Overview

A 300-line HTTP server that hands out SSH private keys and API tokens to authorised machines and agents. IP allow-list, optional X-API-Key header, every request audit-logged. Zero runtime dependencies — no Express, no Redis client, just Node's standard library.

Designed as a sidecar for Consciousness Server and Cortex. Works standalone for any system that needs a small trusted vault without pulling in HashiCorp Vault or a cloud KMS.

Why this exists

If you run a team of AI agents, each one eventually needs credentials — SSH keys to push code, API tokens to call services, bearer tokens to authenticate into your own infrastructure. Three patterns to avoid:

  • .env files scattered everywhere — duplicated across hosts, leaked by git add -A, never rotated.
  • Hard-coded secrets in config — even in private repos, they leak the moment a fork goes public.
  • Full vault (Vault / KMS / Secret Manager) — overkill for a small team; brings its own operational burden.

Consciousness Key Server is the boring middle path: one file you can audit in an afternoon, two layers of authentication, every access logged.

Install

terminal
git clone https://github.com/build-on-ai/consciousness-key-server.git
cd consciousness-key-server
cp auth/allowed-clients.example.json auth/allowed-clients.json
# edit auth/allowed-clients.json: add client IPs and per-client API keys
docker compose up -d
curl http://localhost:3040/health

Default port is 3040 — part of the Consciousness Server ecosystem reserved range 3030–3050. Change via KEY_SERVER_PORT.

Concepts

Vault layout

The on-disk layout under keys/ is deliberately simple — ls tells you what's there. SSH private keys live at keys/ssh/<name> (no extension); API tokens live at keys/<service>/api-key.txt. Set chmod 600 on every file after populating.

Authentication — two layers

  • IP allow-list — bare IPs or /24-style CIDR prefixes in auth/allowed-clients.json. Localhost (127.0.0.1 / ::1) is always allowed.
  • Optional X-API-Key header — one key per client. Rotate per-client without disrupting others. If the caller sends a key, it must match an allow-listed value; if no key is sent, the IP check alone determines access.

Audit log

Every request — success or failure — appends one line to logs/audit.log. Format is line-oriented and stable — pipe it into your SIEM without writing a parser.

logs/audit.log
[2026-04-25T08:00:01Z] IP=10.0.0.20 ENDPOINT=/keys/ssh/git-deploy RESULT=SUCCESS size=3247
[2026-04-25T08:00:03Z] IP=10.0.0.30 ENDPOINT=/keys/ssh/git-deploy RESULT=SUCCESS size=3247
[2026-04-25T14:22:05Z] IP=10.0.0.99 ENDPOINT=/keys/ssh/git-deploy RESULT=FORBIDDEN IP_not_whitelisted
[2026-04-25T14:22:18Z] IP=10.0.0.20 ENDPOINT=/keys/ssh/../etc/passwd RESULT=REJECTED path_traversal_attempt

Common use cases

Fetch an SSH key from a host

any allow-listed host
curl -s http://localhost:3040/keys/ssh/github-deploy \
  -H 'X-API-Key: replace-me-with-a-long-random-string' \
  > ~/.ssh/id_deploy
chmod 600 ~/.ssh/id_deploy

Fetch an API token

any allow-listed host
curl -s http://localhost:3040/keys/api/openai \
  -H 'X-API-Key: replace-me-with-a-long-random-string' \
  | jq -r .api_key

Fleet SSH key distribution

One deploy key in the vault on the primary host. Every other host (GPU box, dev laptop, CI runner) fetches the key at boot via a systemd oneshot or /etc/rc.local. Zero .env files on the fleet; rotation is one operation on the primary host. Every fetch shows up in the audit log so you know exactly who pulled what and when.

Consciousness Server auth-token distribution

Consciousness Server can fetch its own bearer token from the vault at startup, so you don't put AUTH_TOKEN in .env. Rotation becomes a vault operation, not a redeploy. Native support is planned for CS v0.2; today integrate from your deploy script.

Per-agent credential scoping

Each agent in your fleet gets its own X-API-Key client identity, with per-client audit log entries. "Who fetched OPENAI_API_KEY yesterday at 3 am?" is one line in logs/audit.log away.

API

Five endpoints. The whole surface area.

Method Path Purpose
GET /health Health + uptime
GET /keys/list List available SSH keys and API services
GET /keys/ssh/:name Get an SSH private key (text/plain response)
GET /keys/api/:service Get an API key (JSON response)
GET /audit Last 100 audit-log entries

Threat model

Defends against

  • Accidental disclosure from git push — keys live outside the repo entirely.
  • Shared-secret-in-env-file leaks — rotate one vault entry, not ten .env files.
  • Path-traversal probes — hard-coded rejection of .. and / in key names.
  • Silent access — every request appends to the audit log, including denials and rejections.

Does not defend against

  • A compromised host inside the IP allow-list — IP authentication only.
  • Weak or leaked X-API-Key values — you set them; keep them long and random.
  • Lack of TLS — service speaks plain HTTP. Wrap in a reverse proxy with TLS for cross-host use.
  • A malicious reader on the same filesystem as the vault — use OS permissions; the vault is not a sandbox.

For higher-trust deployments, the obvious upgrades are: terminate TLS at a reverse proxy, run behind a private network or VPN, set tight OS file permissions on keys/, and rotate X-API-Key values on a schedule. The threat model is written for low-friction LAN use; harden as the perimeter widens.

Next steps