# 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: AMLVUGoP2hlEd02nWWghAiVYT4jtiXv50WsZyQ2MbpP/ Unseal Key 2: OtaDsNoGE2EF6UfrQUkU0NoDVxPK/KwBFg9cUfQuhBs+ Initial Root Token: hvs.rKzgIc5aaucOCtlJNsUdZuEH { "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=true \ allowed_uri_sans="urn:device:*" \ allowed_other_sans="" \ require_cn=false \ cn_validations= \ 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). - Nginx fix for DER CRL format ```bash # sed -i 's/\r$//' ./nginx/nginx_ssl/int_iot.crl curl http://vault.local:8200/v1/pki_iot/crl -o nginx/nginx_ssl/int_iot.crl openssl crl -in ./nginx/nginx_ssl/int_iot.crl -out ./nginx/nginx_ssl/int_iot.crl.clean -outform PEM mv ./nginx/nginx_ssl/int_iot.crl.clean ./nginx/nginx_ssl/int_iot.crl curl http://vault.local:8200/v1/pki_root/crl -o nginx/nginx_ssl/root_iot.crl openssl crl -in ./nginx/nginx_ssl/root_iot.crl -out ./nginx/nginx_ssl/root_iot.crl.clean -outform PEM mv ./nginx/nginx_ssl/root_iot.crl.clean ./nginx/nginx_ssl/root_iot.crl (sed 's/\r$//' ./nginx/nginx_ssl/int_iot.crl; echo; sed 's/\r$//' ./nginx/nginx_ssl/root_iot.crl; echo) \ > ./nginx/nginx_ssl/iot.crl ```