Docs

Bunker (NIP-46)

Connect to a remote signing service for enhanced security and automation.

What is a Bunker?

A bunker (defined in NIP-46) is a remote signing service that holds your private key and signs requests on your behalf. Instead of your key living in your browser or CLI, it stays securely on a separate server or device.

Think of it like a hardware wallet for your Nostr identity - the key never leaves the secure environment, and all signing requests go through it.

Bunker Auth Flow

Bunker auth lets Redshift use your Nostr identity without holding your private key. Redshift and the bunker exchange encrypted NIP-46 messages through shared relays.

Redshift CLI

Creates a client key and asks for signatures

Relays

Pass encrypted messages only

nak bunker

Keeps the private key and signs

Relays help Redshift and the bunker find each other, but they cannot read the encrypted requests or access your private key.

When to Use a Bunker

CI/CD Pipelines

Run builds that need secrets without embedding your nsec in environment variables.

Enhanced Security

Keep your key on a hardened server or air-gapped device.

Mobile Signing

Use your phone as a signing device for desktop sessions.

Individual Automation

Keep one individual's signing key outside the CLI process while automating approved requests.

Choosing a Bunker Strategy

The right bunker depends on your use case. Here's our recommendation matrix:

SolutionBest ForSetup TimePlatform
nak bunker RecommendedIndividual CLI, CI/CD, self-hosted2 minmacOS, Linux, Windows
nsec.appPersonal use, cross-platform1 minWeb, iOS, Android
AmberMobile-first users5 minAndroid only

Current scope: individual NIP-46

Redshift v0.14.0 verifies an individual remote-signer workflow with the pinned nak v0.19.7 test fixture. Shared custody, role-based access, invitations, organizational recovery, and SSO are not launched. Upstream bunker client authorization is not a Redshift team-access or compliance control.

Jump to the tested reference →

Bunker URI Format

Bunker connections use a special URI format:

bunker://<signer-pubkey>?relay=<relay-url>&secret=<connection-secret>

# Example:
bunker://3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d?relay=wss://relay.nsecbunker.com&secret=abc123

The URI contains:

  • signer-pubkey - The public key of the bunker that will sign for you
  • relay - The relay used for communication between client and bunker
  • secret - A shared secret to authenticate the connection

Connecting to a Bunker

Web Admin

  1. Go to /admin
  2. Click "Connect"
  3. Select "Bunker URL (NIP-46)"
  4. Paste your bunker URI
  5. Click "Connect"
  6. Approve the connection in your bunker app (if required)

CLI

# Interactive
redshift login
# Select "Use bunker URL"
# Paste your bunker URI

# One-time pairing URI (hidden input; never exposed through process argv)
redshift login --bunker-stdin

# NostrConnect flow (scan QR with bunker app)
redshift login --connect

# Environment variable (for CI/CD)
export REDSHIFT_BUNKER="bunker://..."
redshift secrets list

Bunker Options

nak bunker (Individual & CI/CD)

Tested reference: individual CLI, CI/CD, self-hosted infrastructure Pinned in tests

Redshift's local and release gates exercise nak v0.19.7. Operators must assess upstream security, persistence, availability, and upgrades for their own environment.

Why use the pinned nak reference?

  • Verified interoperability - Redshift tests the exact pinned version through a real local relay
  • Separate signer process - The Redshift CLI does not need the signing key
  • Explicit client authorization - Upstream controls can limit client pubkeys, but do not provide Redshift RBAC
  • Operator-owned deployment - Persistence, hardening, monitoring, and recovery remain your responsibility

Installation

# Install via Go
go install github.com/fiatjaf/[email protected]

# Or download pre-built binary from releases:
# https://github.com/fiatjaf/nak/releases

# Verify installation
nak --version

Quick Start

# Generate a new bunker key and save it locally.
# Keep this file private; it is the signing key for the bunker.
mkdir -p ~/.redshift
chmod 700 ~/.redshift
nak key generate > ~/.redshift/bunker.key
chmod 600 ~/.redshift/bunker.key

# Start the bunker in the background without printing the key in your shell history.
# Its output is saved so Redshift can read the generated bunker:// URL for you.
nak bunker --sec "$(cat ~/.redshift/bunker.key)" relay.damus.io nos.lol   > ~/.redshift/bunker.log 2>&1 &
echo $! > ~/.redshift/bunker.pid

# Wait for nak to print the bunker URL, then export it.
until grep -q 'bunker: bunker://' ~/.redshift/bunker.log; do sleep 0.2; done
export REDSHIFT_BUNKER="$(awk '/bunker: bunker:/// { print $2 }' ~/.redshift/bunker.log | tail -n 1)"

# Connect Redshift without placing the one-time pairing secret in process argv.
redshift login --bunker-stdin
# Paste the REDSHIFT_BUNKER value at the hidden prompt.

# Re-authenticate an existing Redshift CLI profile through the same protected input path.
redshift login --force --bunker-stdin

Persistent Operation Boundary

A long-running bunker is independent infrastructure that you operate. Review the pinned upstream version's persistence, authorization, service supervision, backup, upgrade, and recovery documentation before relying on it. Redshift does not currently provide managed bunker hosting, shared custody, organizational recovery, compliance certification, or an identity-provider bridge.

github.com/fiatjaf/nak →

nsec.app (Third-Party Signer)

Compatibility is not release-certified

nsec.app is an independent service. Review its custody, privacy, availability, and current NIP-46 compatibility before using it; Redshift's release evidence does not certify it.

  1. Visit nsec.app
  2. Create an account or import your existing nsec
  3. Use the NostrConnect flow in Redshift:
# Generate a nostrconnect:// URI
redshift login --connect

# Paste the URI into nsec.app to authorize
nsec.app →

Amber (Third-Party Android Signer)

Compatibility is not release-certified

Amber is independent software. Review its custody model and current NostrConnect/NIP-46 compatibility; Redshift's release evidence currently certifies only the pinned nak fixture.

  1. Download Amber from GitHub or F-Droid
  2. Import or create your Nostr identity
  3. Scan the nostrconnect:// QR code from Redshift
# Generate QR code for Amber to scan
redshift login --connect
github.com/greenart7c3/Amber →

nsecbunkerd (Advanced Self-Hosting)

Advanced: External services unavailable

The hosted admin interface (app.nsecbunker.com) is currently offline. Use CLI-only administration or consider nak bunker instead.

nsecbunkerd is a Docker-based bunker daemon with multi-user features. It can still be self-hosted and administered via CLI, but the web admin interface is unavailable.

# Clone and configure
git clone https://github.com/kind-0/nsecbunkerd.git
cd nsecbunkerd
cp .env.example .env
# Edit .env: Add your npub to ADMIN_NPUBS

# Start with Docker
docker compose up -d

# CLI administration (web admin unavailable)
docker compose exec nsecbunkerd npm run nsecbunkerd -- add --name "my-key"
docker compose exec nsecbunkerd cat /app/config/connection.txt
github.com/kind-0/nsecbunkerd →

CI/CD Integration

Bunkers are ideal for CI/CD because you don't need to store your nsec in CI secrets:

# GitHub Actions example
name: Deploy
on: push

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
      
      - name: Install Redshift
        run: curl -fsSL https://redshiftapp.com/install | sh
        
      - name: Deploy with secrets
        env:
          REDSHIFT_BUNKER: ${{ secrets.REDSHIFT_BUNKER }}
        run: |
          redshift setup --project my-app --environment production
          redshift run -- npm run deploy

For CI/CD, you'll need a bunker running on persistent infrastructure (not ephemeral CI runners). Options include:

  • Self-hosted nak bunker - Run on a small VM or container in your infrastructure
  • nsec.app - Hosted service, authorize your CI runner's client pubkey
  • Amber on a dedicated device - Physical device for high-security environments

Individual CI/CD boundary

Use a dedicated signer identity and narrowly authorized client for each automation context. Upstream allowlists do not provide Redshift team RBAC, approval workflows, or shared recovery.

How It Works

The NIP-46 flow:

  1. Redshift generates a temporary local key pair for the session
  2. It connects to the bunker via the specified relay
  3. When signing is needed, Redshift sends an encrypted request to the bunker
  4. The bunker decrypts the request, signs the event, and sends back the signature
  5. Redshift receives the signature and publishes the event

All communication is encrypted end-to-end. The relay cannot read the signing requests or responses.

Security Considerations

  • Bunker security is critical - A compromised bunker means a compromised identity
  • Use WSS relays - Use encrypted relay transport except for explicit loopback development
  • Rotate secrets - Periodically regenerate bunker connection secrets
  • Monitor usage - Watch for unexpected signing requests
  • Limit permissions - Configure the bunker to only allow necessary operations

Operator security boundary

A remote signer moves key custody; it does not make the workflow compliant or managed. Harden, monitor, back up, and recover the signer according to your own threat model, and test revocation before unattended use.

Troubleshooting

"Failed to connect to bunker" or "unauthorized"

  • Check that the bunker service is running
  • Verify the relay URL is correct and accessible
  • Ensure the connection secret matches
  • Quote the full bunker:// URL. In most shells, an unquoted &secret=... is treated as a background command separator, so Redshift receives the URL without the secret.

"Connection timed out"

  • The bunker may require manual approval - check your bunker app
  • Network issues between client and relay
  • Bunker server may be overloaded

"Signing request rejected"

  • The bunker may have permission restrictions
  • Manual approval was denied
  • Rate limiting triggered