storage/SECRETS.md
Sergei Poljanski 61e93b64c8
All checks were successful
Deploy storage stack / deploy (push) Successful in 20s
Give the bingo photos their own bucket
The datacenter bingo photos sat under bingo/ in asxpio-invoices, next to
the invoice PDFs, guarded only by a prefix policy. Move them to a
datacenterbingo-photos bucket: asxpio's user gets read-write for the
admin's uploads, the bingo user read-only on the whole bucket.

Existing objects are mirrored over with their keys unchanged, so the
database rows stay valid. Both users keep their old access until the
apps are switched and the old prefix is removed.

Assisted-by: Claude:opus-5
2026-10-12 04:07:41 +04:00

4.5 KiB

Forgejo secrets — storage repo

Add these to git.czsk.it/asxpi/storage → Settings → Actions → Secrets before the first deploy. All values are opaque to the storage stack; nothing is domain-specific.

How to generate a value

openssl rand -hex 32       # 64-char hex, good for any password/key
openssl rand -base64 24    # 32-char base64, fine for MinIO root password

For MinIO access keys prefer alphanumeric, 20 chars:

LC_ALL=C tr -dc 'A-Z0-9' </dev/urandom | head -c 20; echo

For MinIO secret keys, 40+ chars:

LC_ALL=C tr -dc 'A-Za-z0-9' </dev/urandom | head -c 40; echo

Required secrets

Deploy access (same pattern as the asxpio repo)

Secret Value
DEPLOY_IP Production host IP/hostname.
DEPLOY_USER SSH user on the prod host.
DEPLOY_SSH_KEY Private SSH key authorised on the prod host.

Reuse the same key the asxpio repo uses.

Postgres

Secret Value
POSTGRES_PASSWORD Postgres superuser password. openssl rand -hex 32. Used only by init/admin.

MinIO

Secret Value
MINIO_ROOT_USER Root username, e.g. storage-admin. Any string ≥ 3 chars.
MINIO_ROOT_PASSWORD Root password. ≥ 8 chars; use openssl rand -base64 24.

Per-app credentials provisioned for asxpio

These are also added (with the same values) on the asxpio repo so the app can connect.

Secret Value
ASXPIO_DB_PASSWORD Postgres password for the asxpio role. openssl rand -hex 32.
ASXPIO_S3_ACCESS_KEY 20-char alphanumeric, see snippet above.
ASXPIO_S3_SECRET_KEY 40-char alphanumeric, see snippet above.

Per-app credentials provisioned for datacenterbingo

These are read-only:

  • Role bingo gets SELECT on bingo_datacenters and bingo_incidents in the asxpio DB, and default_transaction_read_only.
  • The MinIO user may only GetObject in the datacenterbingo-photos bucket (and, until the migration is cleaned up, under asxpio-invoices/bingo/). asxpio's user has read-write on that bucket for the admin's uploads.

The same values go on the datacenterbingo repo.

Secret Value
BINGO_DB_PASSWORD Postgres password for the bingo role. openssl rand -hex 32.
BINGO_S3_ACCESS_KEY 20-char alphanumeric.
BINGO_S3_SECRET_KEY 40-char alphanumeric.

The table grants need asxpio's migrations to have run. On a fresh install, deploy storage again after asxpio's first boot.

After adding secrets

  1. Push to main. The Forgejo workflow brings Postgres and MinIO up, then runs postgres-init (creates asxpio role + DB) and minio-init (creates asxpio-invoices bucket and an asxpio-scoped user).
  2. Confirm both init containers exited 0:
    ssh deploy@prod 'docker compose -f /opt/storage/docker-compose.yml ps'
    ssh deploy@prod 'docker logs storage-postgres-init storage-minio-init'
    
  3. Add the matching ASXPIO_DB_PASSWORD, ASXPIO_S3_ACCESS_KEY, ASXPIO_S3_SECRET_KEY (plus ADMIN_USER, ADMIN_PASSWORD) on the asxpio repo — see asxpio/SECRETS.md.
  4. Deploy asxpio.

Rotation

  • POSTGRES_PASSWORD / MINIO_ROOT_PASSWORD: update secret, push. Init scripts only touch per-app roles, so the root passwords are applied on container restart (Postgres) or via the env on next boot (MinIO). For MinIO root rotation, recreating the container is enough.
  • Per-app password / keys: update both repos' secrets, push storage first (re-provisions the role/user with the new password), then push the consumer.