# Vault setup ```bash export VAULT_ADDR=http://localhost:8200 export VAULT_TOKEN=root # Enable KV v2 (if not already): vault secrets enable -path=kv kv-v2 vault secrets enable -path=kv kv-v2 # Put secrets (example) vault kv put kv/snoop \ db_dsn="postgres://snoop:snoop@postgres:5432/snoop?sslmode=disable" \ minio_endpoint="minio:9000" \ minio_access_key="minioadmin" \ minio_secret_key="minioadmin" \ minio_use_ssl="false" \ jwt_secret="supersecretjwt" \ minio_records_bucket="records" \ minio_livestream_bucket="livestream" \ minio_presign_ttl_seconds="900" ``` Unseal Key 1: XdERN+/hxR9RjLC/S8c+y0omToYvB7Qs1jaUenZQvphD Unseal Key 2: VBhPBtYcq1GAk7ByPfAsamxV4tJOZ49chAYxxOvc49Oj Initial Root Token: hvs.tZ4eh9P18sCZ5c1PZIz59EmH { "db_dsn": "postgres://snoop:snoop@postgres:5432/snoop?sslmode=disable", "minio_endpoint": "minio:9000", "minio_access_key": "minioadmin", "minio_secret_key": "minioadmin", "minio_use_ssl": "false", "jwt_secret": "supersecretjwt", "minio_records_bucket": "records", "minio_livestream_bucket": "livestream", "minio_presign_ttl_seconds": "900" } ### Stand up internal CA (root + intermediate) ```bash # Enable PKI backends (root + intermediate) vault secrets enable -path=pki_root pki vault secrets tune -max-lease-ttl=87600h pki_root # 10y vault write pki_root/root/generate/internal \ common_name="Snoop Root CA" key_type=ec key_bits=256 ttl=87600h vault secrets enable -path=pki_iot pki vault secrets tune -max-lease-ttl=17520h pki_iot # 2y # Create an intermediate CSR vault write -field=csr pki_iot/intermediate/generate/internal \ common_name="Snoop IoT Intermediate" key_type=ec key_bits=256 ttl=17520h > iot_int.csr # Sign intermediate with root vault write -field=certificate pki_root/root/sign-intermediate csr=@iot_int.csr \ format=pem_bundle ttl=17520h > iot_int_signed.pem vault write -field=issuing_ca pki_root/root/sign-intermediate \ csr=@iot_int.csr format=pem_bundle ttl=17520h > root_ca.pem # Set the signed intermediate in Vault vault write pki_iot/intermediate/set-signed certificate=@iot_int_signed.pem ``` ### Configure URLs + a role for devices ```bash # Publish issuing + CRL URLs (Nginx will fetch CRL periodically) vault write pki_iot/config/urls \ issuing_certificates="https://vault.example.local/v1/pki_iot/ca" \ crl_distribution_points="https://vault.example.local/v1/pki_iot/crl" # Role that limits cert subjects to your device GUIDs vault write pki_iot/roles/device \ allow_any_name=false \ allowed_uri_sans="urn:device:*" \ allowed_other_sans="" \ allow_ip_sans=false \ allowed_domains="" \ enforce_hostnames=false \ key_type=ec key_bits=256 \ max_ttl=720h ttl=720h # 30 days ``` ### Enrollment flow (device CSR → signed cert) - Device side - Generate keypair on the device (never export private key). - Create CSR with CN= and URI SAN urn:device:. - Server side - Backend verifies a one-time enrollment token (or pre-shared bootstrap secret), calls: ```bash vault write pki_iot/sign/device \ csr=@device.csr \ uri_sans="urn:device:" \ ttl=720h > device_cert.pem ``` ### Revocation - Immediate kill: your backend stores bad serials; deny in app logic. - CRL: `vault write pki_iot/revoke serial_number=""`. - Fetch CRL periodically to a local file for Nginx: ```bash curl -fsSL https://vault.example.local/v1/pki_iot/crl -o /etc/nginx/iot.crl nginx -s reload ``` - Automate via systemd timer/cron (e.g., every 10–15 min).