Self-hosted · AGPL-3.0 · built for engineering teams

CorvusControl every secret.

Store credentials, certificates, and configuration in one place. PostgreSQL row-level security enforces access at the database, while audit logs record every sensitive action.

Access model

team project secret

A secret can inherit project permissions or use explicit bindings only. Reveal goes through an approval workflow and issues a time-limited grant.

local / compose eval only
export GLOBAL_ADMIN_EMAIL=you@example.com
ALLOW_INSECURE_DEFAULTS=1 \
  podman-compose up -d --build

# UI        http://localhost:8080
# PostgREST http://localhost:3000
PostgreSQL row-level security Full audit logging Self-hosted deployment Kubernetes-ready API

Capabilities

Manage access, rotate credentials, and connect workloads through the browser, CLI, machine API, or PostgREST.

01

Access control

  • RBAC at team, project, and secret scope
  • LDAP / OIDC groups
  • Reveal approval with time-limited grants
  • PATs and scoped machine accounts
  • TOTP + single-use recovery codes
02

Operations

  • Expiry dashboards, trash, version history
  • Structured kinds: URL, cert, SSH key, KV
  • Searchable custom metadata
  • Bulk import / export: .env, JSON, CSV
  • Audit logs, access review, retention purge
03

Integrations

  • External Secrets Operator pull and push
  • Unified machine API at /eso/v1
  • PostgREST for SQL-style metadata queries
  • corvus CLI: get, apply, reveal, approve, deny
  • SMTP for resets, alerts, verification

Security model

RLS in PostgreSQL rejects unauthorized rows even when application code is wrong.

Layer Control
Encryption Fernet (AES-128-CBC + HMAC) at rest via MASTER_KEY. Optional per-project data-encryption keys.
Key protection An optional HSM stores master-key material outside the application. Local HSM state lives in hsmdata.
Authorization PostgreSQL RLS policies. SECURITY DEFINER functions for auth flows.
Sessions Server-side sessions with per-device revocation. Login lockout after 5 attempts / 5 minutes.
Credentials bcrypt hashing in SQL. Production refuses to start without strong generated secrets.

How you use it

Use the browser for daily work, the CLI for shells and CI, and the machine API for workloads. Kubernetes connects through External Secrets Operator.

Interfaces

  • Browser UI: search, bulk actions, versions, reveal approvals, import and export.
  • Unified secret API: /eso/v1 with machine tokens or PATs.
  • PostgREST: SQL-style metadata queries and an External Secrets Operator provider.
  • CLI: corvus for shells and CI. Python 3 stdlib only.

Deploy

  • Docker or Podman Compose for local and small deploys.
  • Kubernetes with a Kustomize base and overlays.
  • Ordered SQL migrations run at startup and upgrade existing databases in place.

CLI

corvus-cli is a stdlib-only client for /eso/v1. Binary name is corvus. Machine tokens stay on one project. PATs can switch projects by name and run org commands.

Install

RHEL 9+. Env vars beat ~/.config/corvus/config (mode 0600).

  • SS_URL, SS_TOKEN, SS_PROJECT
  • ss_… machine token: project UUID only
  • pat_… PAT: UUID or unique project name
  • Prefer --from-file / --from-env over --value
install man corvus
sudo install -m 0755 corvus /usr/bin/corvus
sudo install -m 0644 corvus.1 /usr/share/man/man1/corvus.1
# or: make rpm && sudo dnf install -y dist/corvus-cli-*.noarch.rpm
loginPAT or machine token
# Machine token: project UUID only
corvus login \
  --url https://secrets.example.com \
  --token ss_… \
  --project 31a70875-7d6a-40a7-a315-751f8a7ee38f

# PAT: project name is fine
corvus login \
  --url https://secrets.example.com \
  --token pat_… \
  --project ios-app

# CI / no config file
export SS_URL=https://secrets.example.com
export SS_TOKEN=ss_…   # do not commit
export SS_PROJECT=<uuid>

Full command list, org admin verbs, and token scopes: github.com/sigaint-au/corvus-cli

Quick start

The public demo uses seeded mock accounts. Local setup is one compose command. Keep real secrets off both until you deploy for production.

Demo accounts

Password is password for all of them. Evaluation only.

  • Global admin: admin@example.com
  • Engineer: alice@example.com
  • Ops: bob@example.com
  • Viewer: carol@example.com
  • Contractor: dave@example.com
reset local data scripts/reset.sh
scripts/reset.sh        # asks first
scripts/reset.sh --yes  # does not

# Drops pgdata only.
# HSM state stays in hsmdata.

Source and docs

Server source, CLI, and docs. User, admin, and developer guides live under docs/ in the server repo.