Skip to content

Operations

Runbook-oriented guidance for health, metrics, retries, timestamping, and incidents.

CI/CD

Pull requests run restore, build, tests, web lint, and vulnerability audits (.github/workflows/ci.yml). Pushes to main also publish three GHCR images:

ghcr.io/serhatboyraz/opensignature/api:latest
ghcr.io/serhatboyraz/opensignature/worker:latest
ghcr.io/serhatboyraz/opensignature/web:latest

Each image is also tagged sha-<short-sha>. Do not bake secrets or PFX files into images. First-time GHCR packages are private until visibility is changed.

Health

/health/live
/health/ready

Readiness includes required dependencies (PostgreSQL, RabbitMQ, storage as configured).

Metrics to watch

  • Request / completion / failure rates
  • Queue depth and queue wait
  • Processing duration
  • Provider and storage errors
  • Retry count and DLQ depth

Local stack

Full stack:

cp .env.example .env
docker compose up -d --build
docker compose ps
Service URL
Web http://localhost:5173
API http://localhost:5270/health
RabbitMQ UI http://localhost:15672

Infrastructure only: docker compose up -d postgres rabbitmq.

Secrets: PFX_PASSWORD, optional TIMESTAMPING_*OPENSIGNATURE_SECRET_* (see engineering operations).

Full ops notes: engineering operations source.

Worker retry defaults

Setting Typical default
MaxAttempts 5
Initial backoff 1s
Multiplier 2
Max backoff 60s
Lock lease 15 minutes

Permanent failures go to esign.signature.dlq without endless retry.

flowchart TD
  F[Signing failure] --> C{Classifier}
  C -->|Transient| R[Backoff republish]
  R --> M{MaxAttempts?}
  M -->|No| W[Worker retry]
  M -->|Yes| DLQ[DLQ]
  C -->|Permanent| DLQ

Timestamping (RFC 3161)

T/LT/LTA require a TSA. Configure on the worker:

"Timestamping": {
  "Url": "https://tsa.example.invalid/",
  "PolicyOid": "",
  "Username": "",
  "PasswordSecretName": "Timestamping:Password"
}

Missing TSA → TIMESTAMP_AUTHORITY_UNAVAILABLE (no silent downgrade to B).
HTTP Basic Auth: set Username and store the password via user secrets / PasswordSecretName. Leave Username empty for anonymous TSAs.

Incident checklist

  1. Correlation ID / signature ID / job ID
  2. Provider health
  3. Queue esign.signature.worker and DLQ
  4. Storage presence of input.bin / signed.bin
  5. Machine-readable error code
  6. Retry only if classified transient

USB tokens (Development)

With vendor PKCS#11 middleware installed, Development may auto-detect libraries (Signing:SmartCard:AutoDetect). Expired token certificates may sign only when Signing:AllowExpiredCertificates is true — keep false in production.

Full ops notes: engineering operations source.