Skip to content

Keys & Certificates Inventory

Version: 1.0
Date: January 18, 2026
Status: Active

Overview

This document provides a comprehensive inventory of all API keys, secrets, and certificates used in Forma3D.Connect. Each entry includes lifespan, renewal location, and renewal procedures.

IMPORTANT: This document contains references to credentials. Never store actual credentials in version control. All secrets should be stored in: - Azure DevOps Library (Variable Groups) - .env files (local development only, never committed) - DigitalOcean environment variables


Infrastructure

Key/Certificate Purpose Lifespan Renewal Location Renewal Procedure Last Renewed
Droplet SSH Key SSH access to server No expiry (rotate annually) DigitalOcean > Settings > Security > SSH Keys Generate new keypair, add to DO, update ~/.ssh/authorized_keys on droplet YYYY-MM-DD
Droplet Root Password Emergency console access No expiry (rotate annually) DigitalOcean > Droplet > Access > Reset Root Password Reset via DO console, store in password manager YYYY-MM-DD
TLS Certificate (Let's Encrypt) HTTPS for API/Web 90 days Let's Encrypt via Traefik ACME Auto-renewed by Traefik (see below) Auto

Database

Key/Certificate Purpose Lifespan Renewal Location Renewal Procedure Last Renewed
Database CA Certificate SSL connection to managed DB 1-5 years (provider-managed) DigitalOcean > Databases > Your DB > Connection Details > Download CA Download new CA cert, update deployment config YYYY-MM-DD
Database Password PostgreSQL access No expiry (rotate quarterly) DigitalOcean > Databases > Your DB > Users Reset via provider, update DATABASE_URL in Azure DevOps YYYY-MM-DD

Container Registry

Key/Certificate Purpose Lifespan Renewal Location Renewal Procedure Last Renewed
Container Registry Token Push/pull Docker images No expiry DigitalOcean > Container Registry > API Generate new token, update CI/CD variables YYYY-MM-DD
Cosign Signing Key Container image signing No expiry Self-generated (cosign.key) cosign generate-key-pair, update CI/CD secrets YYYY-MM-DD

External Services

Shopify

Key/Certificate Purpose Lifespan Renewal Location Renewal Procedure Last Renewed
SHOPIFY_API_KEY App identification No expiry Shopify Admin > Apps > Your App > API credentials Regenerate in Shopify admin, update Azure DevOps YYYY-MM-DD
SHOPIFY_API_SECRET App authentication No expiry Shopify Admin > Apps > Your App > API credentials Regenerate in Shopify admin, update Azure DevOps YYYY-MM-DD
SHOPIFY_ACCESS_TOKEN Store-specific access No expiry (unless revoked) Shopify Admin > Apps > Your App Reinstall app or regenerate YYYY-MM-DD
SHOPIFY_WEBHOOK_SECRET HMAC verification No expiry Shopify Admin > Settings > Notifications > Webhooks Regenerate in webhooks settings, update Azure DevOps YYYY-MM-DD

SimplyPrint

Key/Certificate Purpose Lifespan Renewal Location Renewal Procedure Last Renewed
SIMPLYPRINT_API_KEY Print farm API access No expiry SimplyPrint Dashboard > Settings > API Generate new key in dashboard, update Azure DevOps YYYY-MM-DD
SIMPLYPRINT_COMPANY_ID Company identification No expiry SimplyPrint Dashboard > Settings Fixed value, only changes if company re-created N/A
SIMPLYPRINT_WEBHOOK_SECRET Webhook verification No expiry SimplyPrint Dashboard > Webhooks Configure in webhook settings YYYY-MM-DD

Sendcloud

Key/Certificate Purpose Lifespan Renewal Location Renewal Procedure Last Renewed
SENDCLOUD_PUBLIC_KEY Shipping API authentication No expiry Sendcloud Panel > Settings > Integrations > API Generate new integration, update Azure DevOps YYYY-MM-DD
SENDCLOUD_SECRET_KEY Shipping API authentication No expiry Sendcloud Panel > Settings > Integrations > API Generate new integration, update Azure DevOps YYYY-MM-DD

Push Notifications (Web Push / VAPID)

Key/Certificate Purpose Lifespan Renewal Location Renewal Procedure Last Renewed
VAPID_PUBLIC_KEY Web Push subscription (shared with frontend) No expiry Self-generated npx web-push generate-vapid-keys --json, update Azure DevOps (WARNING: regenerating invalidates all push subscriptions) 2026-01-19
VAPID_PRIVATE_KEY Web Push sending (server-side secret) No expiry Self-generated Generate with public key (same command), update Azure DevOps 2026-01-19
VAPID_SUBJECT Contact email for push services N/A Configuration only Update in Azure DevOps if contact email changes 2026-01-19

Initial VAPID key generation:

npx web-push generate-vapid-keys --json
# Output: { "publicKey": "...", "privateKey": "..." }

Warning: Do NOT regenerate VAPID keys unless absolutely necessary. Regenerating keys invalidates all existing push subscriptions across all users. Users will need to re-subscribe for push notifications.


Application

Key/Certificate Purpose Lifespan Renewal Location Renewal Procedure Last Renewed
INTERNAL_API_KEY Dashboard/Admin access No expiry (rotate annually) Self-generated Generate with openssl rand -hex 32, update Azure DevOps YYYY-MM-DD
SENTRY_DSN Error tracking No expiry Sentry Dashboard > Project Settings > Client Keys Create new DSN if needed, update Azure DevOps YYYY-MM-DD
SMTP Credentials Email notifications Varies by provider Email provider dashboard Regenerate password/API key YYYY-MM-DD

CI/CD (Azure DevOps)

Key/Certificate Purpose Lifespan Renewal Location Renewal Procedure Last Renewed
Azure DevOps PAT Pipeline authentication 1 year max Azure DevOps > User Settings > Personal Access Tokens Generate new PAT, update service connections YYYY-MM-DD
SSH Service Connection Deploy to droplet Tied to SSH key Azure DevOps > Project Settings > Service Connections Update with new SSH private key YYYY-MM-DD
Secure Files Certificates and keys N/A Azure DevOps > Pipelines > Library > Secure Files Upload new files as needed YYYY-MM-DD

TLS Certificate Auto-Renewal

Traefik automatically handles Let's Encrypt certificate renewal:

  • Validity: 90 days per certificate
  • Auto-renewal: Traefik renews ~30 days before expiry
  • Storage: Certificates stored in Docker volume traefik-certs at /letsencrypt/acme.json
  • Challenge: HTTP-01 challenge via port 80 (must remain accessible)
  • Configuration: See deployment/staging/traefik.yml > certificatesResolvers.letsencrypt

Monitoring TLS auto-renewal:

# Check certificate expiry date
echo | openssl s_client -connect connect-api.forma3d.be:443 2>/dev/null | openssl x509 -noout -dates

# Check Traefik logs for renewal activity
docker logs forma3d-traefik 2>&1 | grep -i "acme\|certificate\|renew"

# Verify ACME storage file exists
docker exec forma3d-traefik ls -la /letsencrypt/acme.json

Troubleshooting failed renewal: 1. Ensure port 80 is open and reachable from internet 2. Check DNS still points to correct IP 3. Verify Traefik container is running: docker ps | grep traefik 4. Check Traefik logs for ACME errors 5. If needed, remove acme.json and restart Traefik to re-issue certificates


Renewal Calendar

Frequency Items
Weekly (automated) TLS certificates checked by Traefik
Monthly Verify TLS auto-renewal is working
Quarterly Rotate database password, review API key usage
Annually Rotate SSH keys, Azure DevOps PAT, INTERNAL_API_KEY, review all external API keys
Before Expiry Database CA certificate (monitor provider notifications), Azure DevOps PAT
On Incident Rotate any potentially compromised credentials immediately

Renewal Checklist

When renewing any credential:

  1. Generate new credential in source system
  2. Update .env files (staging and production)
  3. Update secrets in Azure DevOps (Library > Variable Groups)
  4. Deploy with new credentials
  5. Verify system still works (health checks)
  6. Revoke old credential (if applicable)
  7. Update this inventory with new "Last Renewed" date

Secure Storage Locations

Location What's Stored Access
Azure DevOps Variable Groups All production secrets Project Administrators
Azure DevOps Secure Files SSH keys, certificates, cosign.key Pipeline only
Password Manager Root passwords, recovery codes Authorized personnel
.env files (local) Development credentials Individual developers

Revision History:

Version Date Author Changes
1.0 2026-01-18 Phase 6 Implementation Initial inventory
1.1 2026-01-19 Phase 7 Implementation Added VAPID keys for Web Push notifications