Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Example Usage & Recipes

This page provides concrete examples for common Sigyn workflows.

Quick Shortcuts

Using Short Aliases

Every major command has a short alias for fast typing:

# These pairs are equivalent:
sigyn secret list --env dev     →  sigyn s list -e dev
sigyn vault list                →  sigyn v list
sigyn env diff dev staging      →  sigyn e diff dev staging
sigyn audit tail                →  sigyn a tail
sigyn sync push                 →  sigyn sy push
sigyn run -e dev -- ./app       →  sigyn r -e dev -- ./app

Top-Level get/set

Skip the secret subcommand for the most common operations:

# Instead of: sigyn secret get DATABASE_URL -e dev
sigyn get DATABASE_URL -e dev

# Instead of: sigyn secret set API_KEY 'new-key' -e prod
sigyn set API_KEY 'new-key' -e prod

# Copy a secret to clipboard
sigyn get API_KEY -e prod --copy

Quick Listing with ls

sigyn ls                  # list secrets in default env
sigyn ls prod             # list secrets in prod (prefix matching)
sigyn ls --vaults         # list all vaults
sigyn ls --envs           # list all environments
sigyn ls dev --reveal     # show secret values

Environment Prefix Matching

Type just enough of the environment name to be unambiguous:

sigyn get API_KEY -e d        # resolves to 'dev'
sigyn get API_KEY -e p        # resolves to 'prod'
sigyn get API_KEY -e st       # resolves to 'staging'
sigyn run -e p -- ./deploy    # run with prod secrets

Context for Repeated Operations

Set a persistent context to avoid typing --vault and --env repeatedly:

sigyn context set myapp prod
sigyn get DATABASE_URL        # uses myapp vault, prod env
sigyn ls                      # lists prod secrets
sigyn run -- ./deploy.sh      # runs with prod secrets

sigyn context clear           # go back to defaults

Inline Secret Refs in Commands

Reference secrets directly in command arguments with {{KEY}}:

sigyn run -e prod -- curl -H "Authorization: Bearer {{API_KEY}}" https://api.example.com
sigyn run -e dev -- psql "{{DATABASE_URL}}"

Watch Mode for Development

Automatically restart your app when secrets change:

sigyn watch -e dev -- npm run dev
sigyn watch -e dev --interval 5 -- cargo run

Useful during development when a teammate updates shared secrets — your local server restarts with the new values automatically.

Working with AI Coding Agents

AI coding assistants (Claude Code, GitHub Copilot, Cursor, Windsurf, etc.) run in your terminal and can read environment variables, .env files, and process listings. Sigyn keeps secrets invisible to them.

The Problem

# DON'T DO THIS — any AI agent in your terminal can read these:
export DATABASE_URL="postgres://prod:[email protected]/myapp"
echo "API_KEY=sk-live-abc123" >> .env
source .env

AI agents can see secrets via env, printenv, cat .env, or /proc/self/environ. Even if the agent doesn’t deliberately exfiltrate them, secrets may appear in conversation logs, tool outputs, or error messages.

Run your app with injected secrets in one terminal, your AI agent in another:

# Terminal 1 — app runs with secrets, isolated from your shell
sigyn run -e dev -- npm run dev

# Terminal 2 — AI agent has no access to the secrets
claude   # or cursor, copilot, etc.

Secrets are injected only into the child process (npm run dev). Your shell — where the AI agent runs — never sees them.

Solution 2: Clean Environment

Use --clean to strip the entire parent environment, injecting only vault secrets:

sigyn run --clean -e dev -- ./myapp

This prevents even inherited environment variables (like AWS_SECRET_ACCESS_KEY from a previous aws configure) from being visible.

Solution 3: Unix Socket (Maximum Security)

For zero-exposure secret access, serve secrets over a Unix socket:

# Start the socket server (owner-only permissions, 0600)
sigyn run serve -e prod --socket /tmp/sigyn.sock &

# Your app reads secrets from the socket at runtime
# No environment variables, no files, no process listing exposure

Solution 4: Named Commands in .sigyn.toml

Set up your project so developers never need to type secrets or export them:

# .sigyn.toml
[project]
vault = "myapp"
env = "dev"

[commands]
dev = "npm run dev"
test = "npm test"
migrate = "npx prisma migrate deploy"
sigyn run dev     # secrets injected, never in your shell
sigyn run test    # same — AI agent can't see them

Quick Comparison

MethodSecrets in env?Secrets on disk?Agent can read?
.env + sourceYesYesYes
export KEY=valYesNoYes
sigyn run execChild onlyNoNo
sigyn run --cleanChild onlyNoNo
sigyn run serveNeverNoNo

Letting AI Agents Run and Debug Your App

The previous section covers keeping secrets away from agents entirely. But what if you need the agent to actually run your app (which needs secrets) for debugging?

Strategy 1: Dev Environment with Non-Sensitive Credentials

The simplest approach — use local/dummy credentials in dev that aren’t actually secrets:

# These dev values aren't sensitive — it's fine if the agent sees them
sigyn secret set DATABASE_URL "postgres://localhost/myapp_dev" -e dev
sigyn secret set REDIS_URL "redis://localhost:6379" -e dev
sigyn secret set API_KEY "sk-test-not-a-real-key" -e dev

Configure .sigyn.toml so the agent just runs commands:

[project]
vault = "myapp"
env = "dev"

[commands]
dev = "npm run dev"
test = "npm test"

The agent can run sigyn run dev, see the app output, debug errors — and the dev credentials aren’t worth protecting because they only work against localhost.

Keep real credentials in staging/prod environments only. The agent works in dev where exposure doesn’t matter.

Strategy 2: Sigyn Run with Output Isolation

Let the agent invoke sigyn run but prevent it from reading individual secret values:

# Agent CAN do this (runs the app, sees stdout/stderr):
sigyn run -e dev -- npm run dev

# Agent CANNOT do this (requires interactive passphrase):
sigyn secret get DATABASE_URL -e dev
# ^ Blocked because the agent doesn't have your passphrase

As long as you don’t cache your passphrase in the agent’s terminal session (don’t run eval $(sigyn agent start) there), the agent can only run pre-configured commands — not extract individual secrets.

Strategy 3: Named Commands as an Allowlist

Define exactly which commands the agent is allowed to run:

# .sigyn.toml
[project]
vault = "myapp"
env = "dev"

[commands]
dev = "npm run dev"
test = "npm test"
lint = "npm run lint"
migrate = "npx prisma migrate dev"
debug = "node --inspect ./src/index.js"

The agent can run sigyn run dev, sigyn run test, sigyn run debug — but can’t invent new commands that extract secrets. Combined with not having the passphrase cached, this acts as an effective allowlist.

Strategy 4: Socket Server for Running Apps

Start the socket server yourself, then let the agent restart the app as needed:

# You start the socket server (once, in your terminal):
sigyn run serve -e dev --socket /tmp/sigyn-dev.sock &

# Your app reads secrets from the socket at runtime.
# The agent can restart the app, read logs, debug — but
# the secret values only flow through the socket, never
# through environment variables the agent could inspect.

This requires your app to support reading from a Unix socket (via SIGYN_SOCK env var), but provides the strongest isolation.

What to Watch Out For

Even with these strategies, secrets can leak through:

  • Application logs — if your app logs Connected to postgres://user:password@host, the agent sees it in stdout. Configure your app to redact credentials from logs.
  • Error messages — database connection errors often include the connection string. Use structured error handling that strips credentials.
  • Core dumps / stack traces — these can contain in-memory secrets. Disable core dumps in dev.

For most teams, Strategy 1 + Strategy 2 is the sweet spot:

# 1. Use non-sensitive dev credentials
sigyn secret set DATABASE_URL "postgres://localhost/myapp_dev" -e dev

# 2. Keep real secrets in staging/prod only
sigyn secret set DATABASE_URL "postgres://prod:[email protected]/myapp" -e prod

# 3. Agent works in dev — can run and debug freely
# .sigyn.toml points to dev by default
# Agent runs: sigyn run dev

# 4. You deploy to prod yourself — agent never touches it
sigyn run -e prod -- ./deploy.sh

CI/CD Integration

For full CI/CD documentation including the GitHub Action reference, all export modes, security best practices, and troubleshooting, see the dedicated CI/CD Integration page.

Quick example:

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Load secrets
        uses: tonybenoy/sigyn/action@main
        with:
          bundle: ${{ secrets.SIGYN_CI_BUNDLE }}
          passphrase: ${{ secrets.SIGYN_PASSPHRASE }}
          vault-ssh-key: ${{ secrets.VAULT_SSH_KEY }}
          vault-repo: [email protected]:myorg/sigyn-vaults.git
          vault: myapp
          environment: prod

      - name: Deploy
        run: ./deploy.sh

Advanced Process Injection

Using with Docker

Injecting secrets into a Docker container without ever writing them to a .env file:

sigyn run exec --env prod -- docker run --env-file <(sigyn run export --format docker) my-app:latest

Or more simply if you want all Sigyn secrets to be env vars in the container:

sigyn run exec --env prod -- docker run my-app:latest

Shell Alias for Development

Add this to your .bashrc or .zshrc to always run your local dev server with Sigyn secrets:

alias dev='sigyn run -e dev -- npm run dev'

Or better yet, use a .sigyn.toml project config with named commands:

# .sigyn.toml
[project]
vault = "myapp"
env = "dev"

[commands]
dev = "npm run dev"

Then just run sigyn run dev – no alias needed.

Team Onboarding and Offboarding

Onboarding a New Team Member

Step 1 — New member creates their identity:

# Bob runs this on his machine
sigyn identity create --name bob --email [email protected]
sigyn identity export --name bob > bob.pub
# Send bob.pub to the team lead (Alice) via a secure channel

Step 2 — Team lead creates a scoped invitation:

# Alice imports Bob's public key and creates an invitation
sigyn identity import bob.pub

sigyn delegation invite create \
  --role contributor \
  --envs dev,staging \
  --patterns '*'
# Produces invitation-<id>.json — send it to Bob

Step 3 — New member clones the vault, accepts, and verifies access:

# Bob clones and accepts in one step
sigyn vault clone [email protected]:team/secrets.git --invitation ./invitation-abc123.json

# Or separately:
# sigyn vault clone [email protected]:team/secrets.git
# sigyn delegation invite accept ./invitation-abc123.json

# Pull the vault to get encrypted secrets
sigyn sync pull

# Verify access works
sigyn policy check $(sigyn identity show bob --json | jq -r .fingerprint) read --env dev
#   Result: ALLOW

sigyn policy check $(sigyn identity show bob --json | jq -r .fingerprint) write --env prod
#   Result: DENY (not in allowed envs)

Offboarding a Team Member

When someone leaves the team, revoke their access and clean up the delegation tree.

Step 1 — Inspect the delegation tree to understand impact:

sigyn delegation tree
# alice (a1b2c3d4...) [owner]
#   bob (e5f6a7b8...) [contributor]
#     carol (c9d0e1f2...) [readonly]    <-- Bob invited Carol
#   dave (a3b4c5d6...) [admin]

Step 2 — Revoke with cascade (removes Bob and everyone Bob invited):

sigyn delegation revoke e5f6a7b8... --cascade
# Revoked: bob (e5f6a7b8...), carol (c9d0e1f2...)
# Master key rotated.

Step 3 — Push changes and rotate high-value secrets:

sigyn sync push

# Rotate any secrets Bob had access to
sigyn rotate key DB_PASSWORD --env dev
sigyn rotate key DB_PASSWORD --env staging
sigyn rotate key API_KEY --env dev
sigyn rotate key API_KEY --env staging

If Carol should keep access, re-invite her directly before revoking Bob, or use sigyn delegation revoke e5f6a7b8... (without --cascade) and manually reassign Carol’s delegation.

Contractor and Temporary Access

Granting Time-Limited Access

Create a time-limited invitation with scoped permissions for a contractor:

sigyn delegation invite create \
  --role contributor \
  --envs dev \
  --patterns "STRIPE_*,PAYMENT_*" \
  --expires 90d
# Produces invitation-<id>.json — send to the contractor

The invitation (and resulting access) expires automatically after 90 days.

Verifying Contractor Constraints

After the contractor accepts, verify what they can and cannot do:

# Allowed: read payment secrets in dev
sigyn policy check <contractor-fp> read --env dev --key STRIPE_SECRET_KEY
#   Result: ALLOW

# Denied: access production
sigyn policy check <contractor-fp> read --env prod --key STRIPE_SECRET_KEY
#   Result: DENY (env not allowed)

# Denied: access secrets outside their pattern
sigyn policy check <contractor-fp> read --env dev --key DATABASE_URL
#   Result: DENY (key does not match allowed patterns)

Cleanup

When the contract ends, either wait for auto-expiry or revoke explicitly:

sigyn delegation revoke <contractor-fp>
sigyn sync push

Complex Policies

Restricting a Member to Specific Keys

Add a member who can only see database-related secrets in the staging environment:

sigyn policy member-add <fingerprint>
  --role readonly
  --envs staging
  --patterns "DB_*,POSTGRES_*"

Implementing a “Break Glass” Auditor

An auditor who can see everything but only in an emergency (monitored via audit logs):

sigyn policy member-add <fingerprint>
  --role auditor
  --envs '*'
  --patterns '*'

MFA Enforcement

Requiring MFA for All Members

Enable MFA globally by setting require_mfa: true in the vault’s global constraints. Every non-owner member will be prompted for a TOTP code on their first access (then a 1-hour session grace period kicks in).

First, have each team member enroll:

sigyn mfa setup -i alice

Then set the policy constraint (as vault owner):

# In the vault policy, set global_constraints.require_mfa = true
sigyn policy show --vault myapp   # verify current policy

MFA for Specific Members

You can also require MFA only for certain members by setting require_mfa: true on their individual member constraints rather than globally. This is useful for restricting high-privilege roles while leaving read-only members unaffected.

Generating New Backup Codes

If a team member loses their backup codes, they can generate a fresh set (the old codes are immediately invalidated):

sigyn mfa backup -i alice

Secret Rotation

Manual Rotation of a Database Password

  1. Rotate the secret in Sigyn:
    sigyn rotate key DB_PASSWORD --env prod
    
  2. Export the new value to update your cloud provider (e.g., AWS RDS):
    NEW_PASS=$(sigyn secret get DB_PASSWORD --env prod)
    aws rds modify-db-instance --db-instance-identifier mydb --master-user-password "$NEW_PASS"
    

Rotation Schedules with Hooks

Rotation hooks are executed directly (no shell) after Sigyn rotates a secret. The new secret value is passed via stdin, not as an environment variable. This prevents the secret from being visible in /proc/<pid>/environ. The environment name is available as $SIGYN_ENV.

Hook commands are validated when saved to policy: shell metacharacters (;, |, &, $, `, \, >, <, (, )) are rejected, and the command name must not contain path traversal (..). Maximum command length is 512 characters.

Automated Database Password Rotation

Create a hook script that reads the new secret from stdin and updates AWS RDS:

#!/usr/bin/env bash
# hooks/rotate-db.sh — called after sigyn rotates DB_PASSWORD
# The new secret value is passed via stdin.
set -euo pipefail

NEW_PASS=$(cat)   # read new secret from stdin
aws rds modify-db-instance \
  --db-instance-identifier mydb \
  --master-user-password "$NEW_PASS"

echo "RDS password updated successfully"

Set a weekly rotation schedule with the hook:

sigyn rotate schedule set -v myapp \
  --key DB_PASSWORD \
  --cron "0 0 * * MON" \
  --grace-hours 48 \
  --hooks hooks/rotate-db.sh

Verify the schedule is active:

sigyn rotate schedule list -v myapp
# KEY            CRON             GRACE  HOOKS              NEXT RUN
# DB_PASSWORD    0 0 * * MON     48h    rotate-db.sh       2026-03-02 00:00 UTC

Test it manually to make sure the hook works end-to-end:

sigyn rotate key DB_PASSWORD --env prod

Monthly Redis Auth Token Rotation

#!/usr/bin/env bash
# hooks/rotate-redis.sh
# The new secret value is passed via stdin.
set -euo pipefail

NEW_TOKEN=$(cat)   # read new secret from stdin
redis-cli -h redis.internal CONFIG SET requirepass "$NEW_TOKEN"
echo "Redis auth token updated"
sigyn rotate schedule set -v myapp \
  --key REDIS_AUTH_TOKEN \
  --cron "0 2 1 * *" \
  --grace-hours 24 \
  --hooks hooks/rotate-redis.sh

First-Time Setup

Using the Onboard Wizard

The fastest way to get started is the guided wizard:

sigyn onboard

This walks you through:

  1. Creating an identity (if none exists)
  2. Creating a vault (auto-detects project name)
  3. Importing .env files found in the current directory
  4. Setting up .sigyn.toml

In CI or non-interactive environments, it prints a checklist instead:

sigyn onboard
# Sigyn Setup Checklist
# ─────────────────────────────────
#   ✓ Identity created
#   ✗ Vault created
#     → sigyn vault create <name>
#   ✗ Project config (.sigyn.toml)
#     → sigyn project init

Smarter Init

sigyn init now offers to create missing identity and vault interactively:

sigyn init
# No identities found. Create one now? [Y/n]
# Identity name: alice
# ...
# No vaults found. Create one now? [Y/n]
# Vault name: myapp (detected from Cargo.toml)
# ...
# ✓ Configuration initialized

Environment Comparison and Cloning

Comparing Environments

Before promoting, check what differs between environments:

# Summary of differences (values hidden)
sigyn env diff dev staging
#   - OLD_DEBUG_KEY (removed)
#   + NEW_STAGING_KEY (added)
#   ~ DATABASE_URL (changed)

# See actual values
sigyn env diff dev staging --reveal

# Machine-readable output
sigyn env diff dev prod --json

Cloning an Environment

Quickly create a copy of an environment for testing:

sigyn env clone dev qa
# ✓ Cloned 'dev' → 'qa' (12 secrets)

# Now customize the QA-specific values
sigyn secret set DATABASE_URL "postgres://qa-db/myapp" --env qa

Editing Secrets in Your Editor

Open all secrets in an environment for bulk editing:

sigyn secret edit --env dev
# Opens $EDITOR with:
#   DATABASE_URL=postgres://localhost/myapp
#   API_KEY=sk-abc123
#   FEATURE_FLAG=true
#
# Make changes, save, close. Sigyn shows a diff and confirms.

Searching Across Environments

Find secrets matching a pattern across all environments in a vault:

# Find all database-related secrets
sigyn secret search 'DB_*'
#   [dev] DB_HOST = ••••••••
#   [dev] DB_PORT = ••••••••
#   [staging] DB_HOST = ••••••••
#   [prod] DB_HOST = ••••••••

# Show actual values
sigyn secret search 'API_*' --reveal

Passphrase Agent (Session Caching)

Avoiding Repeated Passphrase Prompts

When running multiple commands in a session, use the passphrase agent to cache your decrypted key in memory — similar to ssh-agent or gpg-agent.

# Start the agent (prints a shell-eval-able export)
eval $(sigyn agent start)

# First command prompts for your passphrase — then caches it
sigyn secret list -v myapp -e dev

# Subsequent commands skip the passphrase prompt entirely
sigyn secret set API_KEY="new-key" -e dev
sigyn vault create new-project -i alice
sigyn delegation tree

Custom Timeout

By default, cached keys expire after 30 minutes. Adjust with --timeout:

# Cache keys for 2 hours
eval $(sigyn agent start --timeout 120)

# Cache keys for 5 minutes (for quick scripted workflows)
eval $(sigyn agent start --timeout 5)

Locking and Stopping

# Clear cached keys but keep daemon running (next command re-prompts)
sigyn agent lock

# Check agent status
sigyn agent status

# Stop the daemon entirely and zeroize all keys
sigyn agent stop

Agent + Batch Operations

The agent is especially useful when combined with batch commands in a multi-step workflow:

eval $(sigyn agent start)

# All of these run without re-prompting for the passphrase
sigyn vault create api worker web --org acme
sigyn env create dev staging prod
sigyn secret set DB_URL="postgres://localhost" REDIS="redis://localhost" -e dev
sigyn secret import .env.production -e prod --force
sigyn delegation revoke abc123 def456 --cascade
sigyn sync push

Shell Profile Integration

Add this to your .bashrc or .zshrc to auto-start the agent on login:

if [ -z "$SIGYN_AGENT_SOCK" ]; then
  eval $(sigyn agent start --timeout 60)
fi

Webhook Notifications

Setting Up Notifications

Configure a webhook to get notified when secrets change. Webhook URLs must use HTTPS (HTTP is only allowed for localhost during development):

sigyn notification configure
# Webhook URL: https://hooks.slack.com/services/T.../B.../xxx
# Select events: * (all events)
# Shared secret: (optional — used to compute HMAC signature)
# ✓ Webhook configured

When a shared secret is configured, each webhook POST includes an X-Sigyn-Signature header containing an HMAC (blake3 keyed hash) of the JSON payload body. Verify this on the receiving end to authenticate that the request came from Sigyn.

Testing Notifications

Send a test event to verify your webhook works:

sigyn notification test
#   ✓ https://hooks.slack.com/services/T.../B.../xxx
# ✓ Test sent to 1 webhook(s)

Listing Configured Webhooks

sigyn notification list
# Configured Webhooks
# ────────────────────────────────────────────────────────────
#   1. https://hooks.slack.com/services/T.../B.../xxx
#      Events: *

Auto-Sync

Enable auto-sync to automatically push changes after every write:

sigyn sync configure --auto-sync true

# Now every secret set/remove/generate automatically pushes
sigyn secret set API_KEY "new-value" --env dev
# ✓ Set 'API_KEY' in env 'dev'
# note: auto-syncing...

Environment Promotion Workflow

Promoting Secrets Through the Pipeline

A typical workflow: set secrets in dev, then promote through staging to production.

Step 1 — Set secrets in dev:

# Batch set — all at once
sigyn secret set API_KEY="dev-key-abc123" DATABASE_URL="postgres://localhost/myapp_dev" FEATURE_FLAG="true" --env dev

Step 2 — Promote all secrets from dev to staging:

# Preview what will change first
sigyn env promote --from dev --to staging --dry-run
# Would promote: API_KEY, DATABASE_URL, FEATURE_FLAG
# Would overwrite: (none)

# Apply the promotion
sigyn env promote --from dev --to staging

Step 3 — Override staging-specific values:

sigyn secret set DATABASE_URL "postgres://staging-db.internal/myapp" --env staging

Step 4 — Selectively promote to production:

# Only promote specific keys (not DATABASE_URL, which differs per environment)
sigyn env promote --from staging --to prod --keys API_KEY,FEATURE_FLAG

# Production DATABASE_URL is managed separately
sigyn secret set DATABASE_URL "postgres://prod-db.internal/myapp" --env prod

Adding a QA Environment

# Option 1: Clone dev (copies all secrets in one step)
sigyn env clone dev qa

# Option 2: Create empty and promote selectively
sigyn env create qa
sigyn env promote --from dev --to qa

# Either way, QA team can now work with a snapshot of dev secrets

Multi-Project Organization

Scenario

You have one organization with multiple projects — say 3 backend services and 1 frontend app — each with their own environments and secrets. You want centralized access control, minimal GitHub repos for sync, and per-project .sigyn.toml configs so developers just cd into a repo and go.

1. Set up the org hierarchy

sigyn org create acme
sigyn org node create backend  --parent acme --type division
sigyn org node create frontend --parent acme --type division

This gives you:

acme (org)
├── backend (division)
└── frontend (division)

2. Create a vault per project, linked to the org

# Batch create — multiple vaults in one command
sigyn vault create api-service auth-service worker-service --org acme/backend
sigyn vault create dashboard --org acme/frontend

Each vault has independent environments (dev, staging, prod), secrets, and member lists — but inherits org-level policies and git remote configuration.

3. Configure git sync once at the org level

sigyn org sync configure --path acme \
  --remote-url [email protected]:acme-corp/secrets.git

All 4 vaults inherit this single remote. If the frontend team later needs a separate repo, override at the child level:

sigyn org sync configure --path acme/frontend \
  --remote-url [email protected]:acme-corp/frontend-secrets.git

Now acme/backend still inherits the org remote, while acme/frontend uses its own.

4. Add a .sigyn.toml to each project repo

In api-service/:

[project]
vault = "api-service"
env = "dev"
identity = "alice"

[commands]
dev = "cargo run"
migrate = "sqlx migrate run"

In dashboard/:

[project]
vault = "dashboard"
env = "dev"
identity = "alice"

[commands]
dev = "npm run dev"
build = "npm run build"

5. Day-to-day usage

# In api-service/ — secrets come from the api-service vault, dev env
sigyn secret set DATABASE_URL "postgres://localhost/api"
sigyn run dev

# In dashboard/ — secrets come from the dashboard vault, dev env
sigyn secret set VITE_API_URL "http://localhost:8080"
sigyn run dev

# Switch to staging for a deploy
sigyn run exec --env staging -- ./deploy.sh

6. Team access control

Add an org-wide admin who can access all vaults:

sigyn org policy member-add <bob-fp> --role admin --path acme

Add a frontend contractor who can only access dashboard secrets in dev:

sigyn org policy member-add <carol-fp> --role contributor \
  --path acme/frontend --envs dev

Check effective permissions:

sigyn org policy effective <carol-fp> --path acme/frontend
#   Role: Contributor
#   Envs: dev
#   Patterns: *

7. Sync everything

sigyn sync push --vault api-service
sigyn sync push --vault auth-service
sigyn sync push --vault worker-service
sigyn sync push --vault dashboard

Why this works

  • One or two GitHub repos instead of one per vault — git remote inheritance means you set it once at the org level.
  • Per-project isolation — each vault has its own master key, so compromising one doesn’t affect the others.
  • Per-project .sigyn.toml — developers just cd into a repo and sigyn run dev picks up the right vault, env, and identity automatically.
  • Cascading RBAC — add someone at acme and they get access everywhere; add them at acme/frontend and they only see frontend vaults.
  • Independent environments — api-service can be on staging while dashboard is still on dev.

Monorepo with Shared Secrets

Scenario

You have a monorepo with 3 services (API, worker, web frontend) that share some infrastructure secrets (database URL, Redis URL) but also have service-specific secrets (API keys, signing tokens). You want each service to see only what it needs while avoiding duplication of shared values.

1. Create the vaults

sigyn vault create shared-infra api-service worker-service web-frontend

2. Populate shared and per-service secrets

# Batch set — multiple KEY=VALUE pairs per command
sigyn secret set DATABASE_URL="postgres://db.internal/myapp" REDIS_URL="redis://redis.internal:6379" -v shared-infra -e prod

sigyn secret set STRIPE_SECRET_KEY="sk_live_..." JWT_SECRET="..." -v api-service -e prod

sigyn secret set QUEUE_URL="https://sqs.us-east-1.amazonaws.com/..." DEAD_LETTER_ARN="arn:aws:sqs:..." -v worker-service -e prod

sigyn secret set NEXT_PUBLIC_API_URL="https://api.example.com" -v web-frontend -e prod

# Or import from a .env file
sigyn secret import .env.production -v api-service -e prod --force

3. Per-directory .sigyn.toml files

In services/api/.sigyn.toml:

[project]
vault = "api-service"
env = "dev"

[commands]
dev = "cargo run"

In services/worker/.sigyn.toml:

[project]
vault = "worker-service"
env = "dev"

[commands]
dev = "cargo run"

In services/web/.sigyn.toml:

[project]
vault = "web-frontend"
env = "dev"

[commands]
dev = "npm run dev"

4. Compose shared + service secrets at runtime

Use sigyn run export to merge secrets from multiple vaults:

# In services/api/ — load shared infra secrets, then layer on API-specific ones
eval $(sigyn run export -v shared-infra --env prod --format shell)
exec sigyn run exec --env prod -- ./api-server

Or in a wrapper script (services/api/start.sh):

#!/usr/bin/env bash
set -euo pipefail

# Export shared secrets into the environment
eval $(sigyn run export -v shared-infra --env "${SIGYN_ENV:-dev}" --format shell)

# Run with service-specific secrets layered on top
sigyn run exec --env "${SIGYN_ENV:-dev}" -- "$@"
# Usage
cd services/api && ./start.sh cargo run

Emergency Breach Response

Full Breach — All Secrets Compromised

If you suspect a broad compromise (e.g., vault key leaked), use breach mode to rotate everything and revoke all delegated members in one step.

Step 1 — Activate breach mode:

sigyn rotate breach-mode --force
# All secrets rotated across all environments.
# All delegated members revoked.
# Master key rotated.

Step 2 — Push the rotated vault:

sigyn sync push

Step 3 — Verify the delegation tree is clean:

sigyn delegation tree
# alice (a1b2c3d4...) [owner]
#   (no delegated members)

Step 4 — Update external systems with new secret values:

# Update RDS
NEW_DB_PASS=$(sigyn secret get DB_PASSWORD --env prod)
aws rds modify-db-instance --db-instance-identifier mydb --master-user-password "$NEW_DB_PASS"

# Update Redis
NEW_REDIS_TOKEN=$(sigyn secret get REDIS_AUTH_TOKEN --env prod)
redis-cli -h redis.internal CONFIG SET requirepass "$NEW_REDIS_TOKEN"

# Repeat for all external integrations...

Step 5 — Re-onboard trusted team members:

# Create new invitations for each trusted member
sigyn delegation invite create --role admin --envs '*'
sigyn delegation invite create --role contributor --envs dev,staging
# Send invitations via a verified secure channel

Step 6 — Audit, verify, and witness:

# Export the audit log for incident documentation
sigyn audit export --output incident-audit.json --format json

# Verify the audit chain is intact
sigyn audit verify

# Have a second team member countersign the recovery
sigyn audit witness

Targeted Response — Single Member Compromise

If only one member’s key was compromised (e.g., stolen laptop), you can scope the response to just that member:

# Revoke the compromised member and their delegates
sigyn delegation revoke <compromised-fp> --cascade
sigyn sync push

# Rotate only the secrets that member had access to
sigyn rotate key DB_PASSWORD --env dev
sigyn rotate key DB_PASSWORD --env staging
sigyn rotate key API_KEY --env dev

# Monitor for suspicious activity
sigyn audit tail -n 100
sigyn audit query --actor <compromised-fp>

Disaster Recovery

Creating Paper Backups

  1. Create 5 shards, requiring 3 to recover:
    sigyn-recovery split --identity alice --threshold 3 --total 5 --output ./shards
    
  2. Print them (or generate QR codes) to store in physical safes:
    sigyn-recovery print-shards ./shards/*.json
    

Recovering a Vault

If Alice loses her laptop, she can reconstruct her identity on a new machine:

sigyn-recovery restore shard1.json shard2.json shard3.json --output recovered_identity.toml
sigyn identity import recovered_identity.toml

Auditing and Compliance

Verifying Audit Chain Integrity

Before any compliance review, verify the hash chain has not been tampered with:

sigyn audit verify
# Audit chain OK: 1,247 entries verified, no breaks detected.

Querying Access Patterns

Search the audit log for specific access patterns:

# All production access events
sigyn audit query --env prod

# All actions by a specific member
sigyn audit query --actor a1b2c3d4...

# Combine filters
sigyn audit query --actor a1b2c3d4... --env prod

Exporting for Compliance

Export the full audit trail for external compliance tools or auditors:

# JSON for programmatic analysis
sigyn audit export --output audit-q1-2026.json --format json

# CSV for spreadsheet review
sigyn audit export --output audit-q1-2026.csv --format csv

Witness Countersigning

After sensitive operations (rotation, member changes, breach response), have a second team member countersign the audit entry:

# After a rotation or breach response, the second admin runs:
sigyn audit witness
# Countersigned entry #1247 with fingerprint e5f6a7b8...

Git Anchoring

Anchor the audit trail to a git commit for external tamper-evidence:

sigyn audit anchor -v myapp
# Anchored audit hash abc123... to git commit def456...

Periodic Compliance Script

Automate weekly compliance checks with a cron job:

#!/usr/bin/env bash
# compliance-check.sh — run weekly via cron
set -euo pipefail

echo "=== Sigyn Compliance Check $(date -I) ==="

# Verify audit chain integrity
sigyn audit verify

# Check for secrets due for rotation
sigyn rotate due --env prod --max-age 90

# Export audit log for the past week
sigyn audit export --output "/var/log/sigyn/audit-$(date -I).json" --format json

# Anchor to git
sigyn audit anchor -v myapp

echo "=== Compliance check complete ==="
0 6 * * MON /opt/scripts/compliance-check.sh >> /var/log/sigyn/compliance.log 2>&1

Scripting with Sigyn

Bulk Update from a CSV

# From a .env file (preferred)
sigyn secret import secrets.env --env dev

# From CSV with shell loop
while IFS=, read -r key value; do
  sigyn secret set "$key" "$value" --env dev
done < secrets.csv

Checking for Expiring Secrets

Find secrets that haven’t been rotated in 6 months:

sigyn rotate due --env prod --max-age 180