Deploy: Single-Node
Audience: DevSecOps: engineers deploying vault.svc (the Vault service) as a single instance backed by HCP Vault (or OpenBao). You are either a customer employee operating a Vault for your company, or a kis.ai employee operating one on the customer’s behalf. Either way, this guide assumes you do not have the Vault source code, you have a release tarball, a binary, and a config file to write. Everything here can be done with what’s in the tarball.
Appropriate for: smaller production deployments, customer-prem single-site installations, and dev / staging environments where the trust-plane availability requirement is lower than the consuming platform.
For HA deployments with multiple vault.svc instances, see the HA deployment guide. For deploying vault-agent on each consumer node, see the agent guide.
1. Prerequisites
Section titled “1. Prerequisites”| Requirement | Detail |
|---|---|
| OS | Linux x86_64 / arm64. macOS supported for dev only. |
| Privileged user | Service runs as vault. Do not run as root. |
| Backend storage | A running HCP Vault, OpenBao, Azure Key Vault, or AWS Secrets Manager (HCP/OpenBao are the only ones supported end-to-end in v1; Azure/AWS are scaffolded but phase-4). |
| Filesystem | A persistent local directory for state and cert material (default /var/lib/vault, /etc/vault). |
| Network | One TCP port (default :7999). Outbound to the backend (HCP: 8200; etc.). Outbound HTTPS to Chitragupta (audit.svc, typically :8443) for audit submission. |
| TLS material | mTLS required. PEM-format server cert/key, the CA bundle that signs your clients, and (for HCP/OpenBao) a separate client cert for vault.svc → backend Vault auth. |
| Time | NTP-synced. JWT nbf/exp and cert validity windows assume reasonable wall-clock accuracy. |
2. Install
Section titled “2. Install”2.1 From a release tarball
Section titled “2.1 From a release tarball”sudo install -d -o root -g root /opt/vaultsudo tar -C /opt/vault -xzf vault.svc-${VERSION}-linux-amd64.tar.gzsudo install -d -o root -g vault -m 0750 /etc/vaultsudo install -d -o vault -g vault -m 0700 /var/lib/vaultsudo install -d -o root -g vault -m 0750 /etc/vault/certs2.2 systemd unit
Section titled “2.2 systemd unit”[Unit]Description=vault.svc trust plane (kis Vault server)After=network.target
[Service]Type=simpleUser=vaultGroup=vaultExecStart=/opt/vault/vault.svc server -f /etc/vault/vault.yamlRestart=on-failureRestartSec=2LimitNOFILE=65536
# Hardening — single-node, no shared FS:ProtectSystem=strictProtectHome=trueReadWritePaths=/var/lib/vault /var/log/vaultNoNewPrivileges=truePrivateTmp=trueLockPersonality=trueRestrictSUIDSGID=true
# Resource limits.MemoryMax=1GTasksMax=256
[Install]WantedBy=multi-user.targetsudo systemctl daemon-reloadsudo systemctl enable --now vault.svc3. Bootstrap YAML: single-node
Section titled “3. Bootstrap YAML: single-node”Generate a template:
sudo /opt/vault/vault.svc config generate bootstrap > /etc/vault/vault.yaml# Or pick a specific shape:sudo /opt/vault/vault.svc config listEdit /etc/vault/vault.yaml. Production-style example using HCP Vault
(works against OpenBao identically, swap hcpvault → openbao and
the cert paths):
# Service identity — chassis convention.service: vaultversion: 1.0.0sid: ${HOSTNAME}
# Listener.host: ""port: "7999"zerotrust: true
# Storage backend — HCP Vault (KV-v2) with cert auth.vaultmanager: store: hcpvault: url: https://vault.internal.example.com:8200 certpath: /etc/vault/certs/vault-client.crt keypath: /etc/vault/certs/vault-client.key cacertpath: /etc/vault/certs/issuer.crt authname: vault-cert secretspathprefix: secret certificatespathprefix: kisaicerts retryduration: 2s
# JWT defaults.servicejwt: expiry: 1h httponly: true
vault: # Signing custody — start with inproc; upgrade to pkcs11 / awskms once # the HSM/KMS plan is in place. See the signer-*.yaml examples. signer: type: inproc
# Default transport for the chassis lib-vault clients in this cluster. # Keep "remote" until every consumer node has vault-agent installed # and validated — flipping to "agent" before that breaks consumers. client: transport: remote
# Tenant-aware access rules. See accessrules.yaml example for the# canonical shape, including the mandatory tenant check.accessrules: {}
# Audit emission. Required in prod; the default NoOpEmitter is dev-only.audit: endpoint: https://chitragupta.internal:8443/submit timeout: 5s
# OTLP telemetry.telemetry: collector: otel-collector.internal:4317 insecure: false environment: prod traces: { enabled: true, sampling_rate: 0.1 }3.1 Templates available
Section titled “3.1 Templates available”vault.svc config list # list allvault.svc config generate bootstrap # HCP + inproc + JS rulesvault.svc config generate bootstrap-dev # FsVault (dev only)vault.svc config generate backend-openbao # OpenBao snippetvault.svc config generate backend-azurekv # Azure KV snippet (phase-4)vault.svc config generate backend-awssm # AWS SM snippet (phase-4)vault.svc config generate signer-pkcs11 # HSM signer (phase-5)vault.svc config generate signer-awskms # AWS KMS signer (phase-5)vault.svc config generate accessrules # canonical JS rule samplevault.svc config generate agent # reference per-node agent config4. Backend setup (HCP Vault / OpenBao)
Section titled “4. Backend setup (HCP Vault / OpenBao)”A one-time bootstrap of the backend, per the release documentation. Summary:
vault operator init(orbao operator init), unseal with the issued keys, store the root token offline.vault auth enable cert: turn on certificate auth.- Write the kisai-policy granting access to
secret/*andkisaicerts/*. vault write auth/cert/certs/vault-cert display_name=vault_cert policies=kisai-policy certificate=@/etc/vault/certs/vault-client.crtvault secrets enable -path=secret kv-v2vault secrets enable -path=kisaicerts kv-v2
Then point vault.svc’s bootstrap (vaultmanager.store.hcpvault.*) at the
URL + cert paths + the registered authname (vault-cert above).
Validate with vault.svc startup logs, the first successfully connected to vault backend hcpvault should land within 2 s of boot.
5. TLS material
Section titled “5. TLS material”For any non-loopback deployment, two cert pairs:
| Pair | Purpose | Where |
|---|---|---|
| Server cert | Terminates incoming mTLS from consumers / operator | host/port listener |
| Vault client cert | Authenticates vault.svc to HCP/OpenBao | vaultmanager.store.hcpvault.{certpath,keypath} |
Same CA bundle for both (the cluster’s kisai issuer chain). Generate
with vault.svc cert rootca / intermediateca / svccert (the release
documentation covers the procedure end-to-end), or with your existing CA.
# Lock down permssudo chown -R root:vault /etc/vault/certssudo chmod -R 0640 /etc/vault/certs/*.keysudo chmod 0644 /etc/vault/certs/*.crt6. First boot
Section titled “6. First boot”sudo systemctl start vault.svcsudo systemctl status vault.svcVerify:
curl -s http://localhost:7999/version # unauthcurl -s http://localhost:7999/ready # 200 → readycurl -s --cert client.crt --key client.key --cacert ca.crt \ https://localhost:7999/certificate/internal/issuerTail logs:
journalctl -u vault.svc -fLook for successfully connected to vault backend hcpvault (or your
backend’s name) within 2 s of start.
7. Day-2 operations
Section titled “7. Day-2 operations”7.1 Operator commands via the CLI
Section titled “7.1 Operator commands via the CLI”From any host with the kis CLI:
kis vault status --server https://vault.example.com:7999kis vault audit query --since 1hkis vault node-token issue --scope dc=us-west,cluster=prodOperator auth: an mTLS operator cert resolved from the kis context or
--operator-cert / --operator-key. The server enforces the
operator-role scope.
7.2 Issuing a join token (for a vault-agent)
Section titled “7.2 Issuing a join token (for a vault-agent)”kis vault node-token issue \ --scope dc=us-west,cluster=prod \ --ttl 1h \ --uses 1# → hj_v1_n8x2k_a1b2c3d4e5f6g7h8j9k0Give the printed token to the operator running vault-agent init on
the new node. See the agent guide.
7.3 Inspecting the audit chain
Section titled “7.3 Inspecting the audit chain”kis vault audit query --since 24h --actor 'spiffe://kis.ai/customer/acme/...'kis vault audit verify # walks the chain from genesisaudit verify is slow (whole-chain replay); run it as a periodic CI
job rather than interactively.
7.4 Rotating an API-key-style secret
Section titled “7.4 Rotating an API-key-style secret”kis vault put vault:db_password "$(openssl rand -hex 24)" \ --end-date "$(date -u -d '+90 days' +%Y-%m-%dT%H:%M:%SZ)"The previous active record is marked inactive in the entity store but the corresponding vault blob is not deleted immediately; the janitor sweeps expired blobs after a grace window.
8. Backup & restore
Section titled “8. Backup & restore”8.1 What to back up
Section titled “8.1 What to back up”Two stores:
-
Backend (HCP Vault / OpenBao / Azure KV / AWS SM): the source of truth for secret + cert material. Backup is the backend’s responsibility (Vault Raft snapshots, AWS SM is implicitly backed up, Azure KV has its own export). Confirm your backend’s backup procedure runs.
-
Data audit + entity tables:
vault.svcwrites to these. Audit is ALSO mirrored to Chitragupta (audit.svc) for chain durability; the Data block copy is the queryable index. Backup is the Data block operator’s responsibility.
The vault.svc binary itself is stateless, losing the host doesn’t lose
data so long as the backend + Data survive.
8.2 Restoring after host loss
Section titled “8.2 Restoring after host loss”- Provision a new host, same OS, same package install (§2).
- Copy
/etc/vault/vault.yamland/etc/vault/certs/*from config-as-code (your cluster repository). sudo systemctl start vault.svc.- Verify
/readyreturns 200 and the connect log fires within 2 s.
No backend or audit state needs reconstruction; vault.svc picks up where
the previous instance left off.
9. Upgrade
Section titled “9. Upgrade”sudo systemctl stop vault.svcsudo tar -C /opt/vault -xzf vault.svc-${NEW_VERSION}-linux-amd64.tar.gzsudo systemctl start vault.svcDowntime: typically <2 s; consumers using RemoteVaultClient
auto-retry. Read the release notes before crossing a minor version
boundary, backend or signer interface changes are surfaced there.
10. Troubleshooting
Section titled “10. Troubleshooting”| Symptom | Likely cause | Action |
|---|---|---|
/ready returns 503 | Backend not reachable / not authenticated. | journalctl -u vault.svc -n 200: look for failed to connect to <backend>. Verify the backend is up, the auth role exists, the cert file is readable by the vault user. |
vault.svc: refusing prod (fsvault) | Mistake: fsvault is configured with env: prod. | Switch the backend to hcpvault / openbao / your real prod backend. |
| TLS handshake fails on listener | Server cert + client cert chain mismatch. | Verify the CA bundle (cacertpath) signs both. Check cert expiry: openssl x509 -in cert.crt -noout -enddate. |
| Vault token “non-renewable” error in logs | The cert role lacks auth/token/renew-self permission. | Re-apply kisai-policy on the backend. |
| Audit emission failing | The audit endpoint is unreachable. | Verify audit.endpoint resolves and is reachable. Operations continue, but the audit chain is not durable until it does: investigate immediately. |
vault.svc config list returns no examples | Broken release binary: examples weren’t embedded at build time. | Re-download the release tarball and verify checksum; if it persists, file a bug with the build supplier. |
11. Failure modes
Section titled “11. Failure modes”Process crash: systemd restart kicks in. Backend state is unaffected
(it’s external). Consumers using RemoteVaultClient retry transparently
via lib-chassis backoff. Total recovery: under 5 s in normal operation.
Backend down: vault.svc’s connect loop retries (retryduration).
While the backend is unreachable, in-flight secret operations fail
with vault-failed-to-retrieve-secret / vault-not-connected.
Consumers do NOT have a local cache today (the lib-vault secret cache
is wired but disabled, see the consumer guide). Audit + cert
verification paths that rely on cached cert public keys keep working.
Single-node has no redundancy. If the host dies, restore per §8.2. For deployments that need fault tolerance, see the HA deployment guide.
12. Hardening checklist
Section titled “12. Hardening checklist”- All TLS material has
not_after:≤ 12 months. Rotation schedule documented. -
vault.client.transportset explicitly (don’t rely on the default during a migration). - FsVault NEVER referenced in this cluster’s config (search:
grep -r fsvault /etc/vault/). -
vault.signer.type: inproconly if no HSM/KMS is available. Plan documented to move topkcs11/awskms/ similar. - Audit
endpoint:set; no NoOpEmitter fallback. - OTel collector reachable from this host.
- systemd unit runs as non-root
vaultuser. - Bootstrap YAML stored in config-as-code repo.
- Backend operator credentials NOT readable by the
vaultuser (only the leaf client cert is). -
kis vault policy lintpasses against this cluster’s access rules. -
kis vault audit verifyscheduled as a CI / cron job (chain integrity). - Disaster-recovery drill ≤ quarterly: tear down host, restore, validate.