Skip to content

Architecture

OrbitalReg is a Go monolith with a React SPA frontend. State lives in PostgreSQL; artifact bytes live in an S3-compatible object store; session and rate-limiter state lives in Redis. Everything else — scanning, retention, governance, signing — is a goroutine inside the API process.

This page is the externally-rendered companion to docs/ARCHITECTURE.md. The in-repo file remains the canonical engineering source; this page trims internal-team-only sections (release-cadence schedules, postmortems) and keeps the system-shape sections that an evaluating engineer wants.

1. Components

LayerComponentNotes
IngressNGINX Ingress + cert-managerTLS, body-size caps for uploads
FrontendReact SPA in nginxStatic bundle, no runtime state
APIGo (chi, pgx, minio-go)Stateless, 3 replicas, HPA-ready
DBPostgreSQL 16Bring your own, or use CloudNativePG via the chart
CacheRedis 7Session store, rate limiter, metadata cache
Object storeExternal S3-compatibleMinIO, Ceph RadosGW, AWS S3, Cloudflare R2 — anything SigV4-capable
IdentitySAML 2.0 / OIDCBuilt-in or external — Azure Entra ID, Okta, Keycloak
MetricsPrometheus + GrafanaServiceMonitor CRD
LogsLoki + PromtailJSON logs from the Go API
TracesOpenTelemetry / OTLPOptional, off by default

2. Storage flow

text
 client ──(stream upload)──► API ──(stream)──► External S3 bucket
                              │                 (path: aa/bb/<sha256>)
                              └─► Postgres: artifacts(repo_id, path, version,
                                  size, sha256, content_type, metadata)

 client ──(GET)──► API ──(302)──► Presigned URL ──► External S3 bucket

Uploads are content-addressable: the API hashes the request body with a TeeReader while streaming to a staging key, then renames to aa/bb/<digest>. Deduplication is automatic — identical content produces an identical S3 key.

Downloads return HTTP 302 to a presigned S3 URL so artifact bytes never traverse the API process again. The exception is the Docker manifest path, which the API rewrites and serves directly because clients sign the response body.

3. Scanning pipeline

Every uploaded artifact triggers a scan-job DB row. A pool of in-process workers picks rows up, dispatches to the configured scanners (Trivy, Grype, Syft, OSV.dev, format-specific tooling), and writes findings into scan_findings keyed on (artifact_id, scanner, vuln_id).

A single artifact typically produces 10–100 findings across all scanners. The first finding above your project's policy threshold (default: CRITICAL) flips the artifact's quarantined bit, which gates downloads and, if a SecurityBlock matches, hides it entirely.

The full Detection roadmap lives at SCAN-ROADMAP.md.

4. Governance layer

The governance surface is six tables, all admin-CRUDable through both the UI and the REST API:

TablePurpose
security_blocksPattern-match block rules with reason + customer message
retention_policiesPer-repo prune rules (keep-N-newest, keep-by-age, …)
license_policiesPer-project license allow/block lists
quarantine_settingsAuto-quarantine threshold + scope per project
webhook_subscriptionsOutbound HMAC-signed event delivery
oidc_trust_policiesOIDC-token-exchange rules for keyless CI auth

Both the Terraform provider and the Kubernetes operator drive the same tables through the same REST endpoints, so what you can express in clicks you can express in HCL or YAML.

5. Authn / authz

  • Authn: SAML 2.0 (default), local users, or service-account bearer tokens. OIDC token exchange handles workload identity for CI.
  • Authz: Project-scoped roles. viewer / editor / owner per project, plus a global admin role for platform-wide settings. Service accounts get scoped tokens (e.g. read:project:foo, push:project:foo:repo:bar).

6. Backups

Postgres backups go through CloudNativePG + Barman with PITR. Configurable retention; default 30 days. A weekly verification CronJob restores the latest backup into an ephemeral cluster, runs a smoke suite, and writes the result to backup_verification_runs. Failed verifications fire a Prometheus alert.

The S3 bucket is replicated to a second bucket / region using provider-native replication (S3 → S3, MinIO site-replication, Ceph multi-site).

7. What's NOT in OrbitalReg

To keep the operational surface small, we intentionally don't ship:

  • A built-in service mesh (use Linkerd / Istio / Cilium if you want one)
  • A built-in identity provider (use SAML / OIDC against your existing IdP)
  • A built-in object store for production (use S3-compatible storage)
  • A built-in build system (CI integration is via REST + components, not via embedded runners)

The design favours integration with established platform layers over re-inventing them.

Released under the Apache-2.0 License.