Skip to main content

Secrets Rotation

All secrets are stored in Coolify's environment configuration — never in git. After rotating any secret, update the Coolify env var and restart the container.


Viva Webhook Key (VIVA_WEBHOOK_KEY)

This key signs webhook payloads sent from Viva to the API.

How to rotate:

  1. Call the Viva API to get a new webhook key:

    # Demo
    curl -u "<merchant_id>:<api_key>" \
    "https://demo.vivapayments.com/api/messages/config/token"

    # Production
    curl -u "<merchant_id>:<api_key>" \
    "https://www.vivapayments.com/api/messages/config/token"

    Returns { "Key": "new-key-value" }

  2. Update VIVA_WEBHOOK_KEY in Coolify UI for the API container

  3. Restart the API container

  4. Re-verify the webhook URL in the Viva dashboard (the GET /payments/webhook handshake):

    • Viva dashboard → Web Payments → Webhooks → verify URL
    • This triggers Viva to call GET /payments/webhook, which returns { Key: VIVA_WEBHOOK_KEY }
    • If verification passes, Viva will use the new key for signatures

Why re-verify? Viva caches the expected signature key. Changing VIVA_WEBHOOK_KEY without re-verifying means Viva will still send webhooks signed with the old key, and your signature verification will reject them.


SMTP Password (Zoho)

  1. Log in to the Zoho SMTP account at mail.zoho.eu
  2. Navigate to Account Security → App Passwords (if using app-specific password)
  3. Generate a new password / change the account password
  4. Update SMTP_PASS in Coolify for the API container
  5. Restart the API container
  6. Verify by checking that the next email (e.g., next warranty cron, or trigger a test) is delivered

Google OAuth Credentials

Used for customer Google sign-in.

  1. Go to Google Cloud Console → APIs & Services → Credentials
  2. Find the OAuth 2.0 Client ID for pcmr.gr
  3. Rotate the client secret (create new, then delete old after verifying)
  4. Update GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET in Coolify API
  5. Restart the API container
  6. Test Google sign-in on staging first

Hetzner Object Storage Keys

Hetzner Storage Box access credentials.

  1. Log in to Hetzner Cloud Console
  2. Navigate to Object Storage → Access Keys
  3. Create a new access key pair
  4. Update STORAGE_ACCESS_KEY and STORAGE_SECRET_KEY in Coolify API
  5. Restart the API container
  6. Verify by uploading a test file through the staff portal (e.g., add an attachment to an order)
  7. Delete the old access key from Hetzner Console

Do production and staging separately — they use different key pairs.


BETTER_AUTH_SECRET

This key signs all session tokens. Rotating this secret will invalidate all existing sessions — all users will be logged out.

  1. Generate a new secret:
    openssl rand -hex 32
  2. Update BETTER_AUTH_SECRET in Coolify for both the API and web containers (must match)
  3. Restart both containers
  4. All sessions are now invalidated — users must log in again
  5. Notify staff before rotating (they will be logged out)

Only rotate if: The secret is compromised, or you suspect session forgery.


Coolify API Token

Used by GitHub Actions to trigger deploys.

  1. Log in to Coolify (coolify.ctsolutions.gr)
  2. Settings → API Tokens → Create new token
  3. Update COOLIFY_API_TOKEN in GitHub repository secrets:
    • github.com/<org>/<repo> → Settings → Secrets and variables → Actions
  4. Verify by pushing an empty commit and confirming the deploy triggers
  5. Revoke the old token in Coolify

Cloudflare Access

Cloudflare Access OTP codes are ephemeral — no rotation needed. If an email address should be removed from access:

  1. Log in to Cloudflare Zero Trust dashboard
  2. Access → Applications → find the relevant app (Coolify, Staff Portal, Docs)
  3. Policies → remove the email or email domain

Post-Rotation Checklist

After rotating any secret:

  • Secret updated in Coolify UI
  • Container restarted
  • Functionality verified (sign-in, file upload, payment, email)
  • Old secret revoked/deleted from the source system
  • Any dependent systems notified (e.g., staff about BETTER_AUTH_SECRET rotation)