Daemon — ssd
ssd is the SecretServer daemon — a lightweight background service that runs on your servers and provides local secret caching, certificate expiry monitoring, Certificate Transparency alerts, and secret rotation.
On this page
OverviewInstallConfigureRunning ssdsystemd serviceFeaturesEnvironment injectionCertificate expiry monitoringCT log monitoringSecret rotationLocal APIOverview
While the ss CLI is for interactive and scripted access, ssd is a persistent service that:
- Caches secrets locally so processes can read them without a round-trip to the API
- Exposes a Unix socket for fast, low-latency secret retrieval
- Monitors certificate expiry and sends alerts before certs expire
- Polls Certificate Transparency logs for your monitored domains
- Executes secret rotation scripts on a schedule
- Syncs secrets to environment files or directories for legacy applications
Use ss for one-off lookups and scripts. Use ssd when you want always-on monitoring, local caching for high-throughput services, or automatic rotation without cron hacks.
Install
ssd is included in the same release binary as the ss CLI.
# Install via the universal installer (installs both ss and ssd) curl -sSL https://secretserver.io/install | sh # Or via Homebrew (macOS / Linux) brew install afterdark/tap/ss # Verify ssd --version
Binary locations
which ss # /usr/local/bin/ss which ssd # /usr/local/bin/ssd
Configure
ssd reads from ~/.adkm/config.yaml (same file as the CLI). The [daemon] section controls daemon-specific behaviour.
# ~/.adkm/config.yaml
api_key: sk_live_...
api_url: https://api.secretserver.io # or your self-hosted URL
daemon:
socket: /var/run/ssd.sock # Unix socket path
cache_ttl: 300 # Secret cache TTL in seconds (default: 300)
poll_interval: 60 # Background poll interval in seconds (default: 60)
log_file: /var/log/ssd.log # Log file (default: stderr)
log_level: info # debug | info | warn | error
# Certificate expiry alerts
cert_warn_days: [30, 14, 7, 1] # Alert when cert expires in N days
# CT log monitoring (requires ss ct monitor add <domain> first)
ct_poll_interval: 3600 # Check CT logs every hour
# Secret rotation
rotation:
enabled: true
scripts_dir: /etc/ssd/rotate.d/ # Directory of rotation scriptsEnvironment variables
SS_API_KEY=sk_live_... # API key (overrides config file) SS_API_URL=... # API URL (overrides config file) SSD_SOCKET=/var/run/ssd.sock SSD_LOG_LEVEL=info
Running ssd
# Start the daemon (foreground) ssd # Start with verbose logging ssd --log-level debug # Start with a custom config file ssd --config /etc/ssd/config.yaml # Check daemon status (if already running) ssd status # Reload configuration without restart ssd reload # Stop the daemon ssd stop
systemd service (Linux)
Install ssd as a systemd unit for automatic startup and restart.
# /etc/systemd/system/ssd.service [Unit] Description=SecretServer Daemon After=network.target Wants=network-online.target [Service] Type=simple User=ssd Group=ssd ExecStart=/usr/local/bin/ssd --config /etc/ssd/config.yaml Restart=on-failure RestartSec=5 Environment=SS_API_KEY=sk_live_... StandardOutput=journal StandardError=journal [Install] WantedBy=multi-user.target
# Enable and start sudo systemctl daemon-reload sudo systemctl enable ssd sudo systemctl start ssd # Check status and logs sudo systemctl status ssd sudo journalctl -u ssd -f
Features summary
| Feature | Config key | Default |
|---|---|---|
| Local secret cache | daemon.cache_ttl | 300s |
| Unix socket API | daemon.socket | /var/run/ssd.sock |
| Background polling | daemon.poll_interval | 60s |
| Cert expiry alerts | daemon.cert_warn_days | [30,14,7,1] |
| CT log monitoring | daemon.ct_poll_interval | 3600s |
| Secret rotation | daemon.rotation.enabled | false |
| Env file sync | daemon.env_sync.dir | disabled |
Environment injection
ssd can write secrets to an env file that your application sources on startup, or keep it continuously up to date.
# In ~/.adkm/config.yaml:
daemon:
env_sync:
enabled: true
dir: /etc/ssd/secrets/ # Write one file per secret here
env_file: /etc/app/.env # Or write a single .env file
container: production # Only sync secrets from this container
interval: 300 # Refresh every 5 minutes# Application reads from the env file # /etc/app/.env (auto-generated by ssd): # POSTGRES_PASSWORD=s3cur3P@ssw0rd! # STRIPE_SECRET_KEY=sk_live_... # AWS_SECRET_ACCESS_KEY=... source /etc/app/.env && exec myapp
Certificate expiry monitoring
ssd checks all certificates stored in SecretServer and sends alerts when expiry thresholds are crossed.
# In ~/.adkm/config.yaml:
daemon:
cert_warn_days: [30, 14, 7, 1] # Alert at 30, 14, 7, and 1 day before expiry
alerts:
email: ops@example.com # Alert email
webhook: https://hooks.slack.com/... # Slack / Teams webhook
pagerduty_key: abc123 # PagerDuty integration keyAll certificates in the dashboard — including those discovered via ss discover ssl or imported via ss ct import — are included in expiry checks.
CT log monitoring
When domains are added to CT monitoring (via ss ct monitor add), ssd periodically polls Certificate Transparency logs and alerts when new certificates are issued.
# Add a domain to monitor
ss ct monitor add example.com
ss ct monitor add *.example.com
# ssd then polls every ct_poll_interval seconds and alerts on new issuances
# Configure in ~/.adkm/config.yaml:
daemon:
ct_poll_interval: 3600 # every hour
alerts:
email: security@example.comCT monitoring catches mis-issuance events (unexpected CAs issuing certs for your domain), shadow IT, and rogue wildcard certificates before they're used in attacks.
Secret rotation
Place shell scripts in daemon.rotation.scripts_dir. Each script is responsible for rotating one secret type. Scripts are executed on the configured schedule and must exit 0 on success.
# /etc/ssd/rotate.d/postgres-password.sh #!/usr/bin/env bash set -euo pipefail NEW_PASS=$(openssl rand -base64 32) # Update in the database psql "host=db.internal user=admin" -c "ALTER USER app_user PASSWORD '$NEW_PASS'" # Store the new value in SecretServer ss secrets create --name "postgres-password" --value "$NEW_PASS" --update-existing
# In ~/.adkm/config.yaml:
daemon:
rotation:
enabled: true
scripts_dir: /etc/ssd/rotate.d/
schedule: "0 3 * * 0" # Cron expression — every Sunday at 03:00
on_failure: alert # alert | retry | stopLocal Unix socket API
ssd exposes a local Unix socket at /var/run/ssd.sock that applications can query directly — no API key exposed in the process environment.
# Query via curl (using the socket)
curl --unix-socket /var/run/ssd.sock http://localhost/secret/production/postgres-password
# Response:
{ "value": "s3cur3P@ssw0rd!", "cached": true, "cached_at": "2026-02-17T03:00:00Z" }
# Force a cache refresh
curl --unix-socket /var/run/ssd.sock -X POST http://localhost/refresh/production/postgres-passwordClient libraries (Python, Node.js, Go) can be configured to use the local socket instead of the remote API, eliminating network latency for hot paths.