Files
deployment-policies/docs/tech-stack.md
T
jdevega 59cacfdfab
ci / verify (push) Failing after 10m57s
ci / publish (push) Skipped
feat: scaffold deployment-policies monorepo
OPA/Rego deployment gateway policies: 5 rules (valid-environment,
require-approvals, no-self-approval, block-weekends, freeze-window),
a deploy-gate combining them, JSON schemas, scenario-driven tests,
Gitea Actions CI (verify + publish to generic registry), changesets
versioning, Makefile and scripts.
2026-09-15 19:05:03 +02:00

65 lines
3.9 KiB
Markdown

# Tech Stack
## Overview
| Layer | Technology | Version | Purpose |
| --------------- | ---------- | ------- | ------- |
| Policy language | Rego | OPA 1.x (`rego.v1`) | Authoring deployment-gateway policy rules and gates |
| Policy engine | OPA | `v1.20.2` (pinned) | Evaluating, testing, type-checking and bundling the policies |
| Policy linter | regal | `v0.42.0` | Static linting of Rego best practices (optional in CI) |
| Bundles | OPA bundle format | — | Distributable `.tar.gz` bundles (rule modules at `data.rules.*`) |
| Schemas | JSON Schema (draft 2020-12) | — | Static validation of `input` and `data` via `opa check --schema` |
| Versioning | Changesets | `@changesets/cli@3.0.3` | Tracking per-policy version bumps across npm workspaces |
| Changelog formatting | oxfmt | `^0.68.0` | Formatting generated changelogs/changesets via `format: "oxfmt"` |
| Package management | npm workspaces | npm 11 / Node 24 | Monorepo layout (`policies/rules/*`, `policies/gates/*`) |
| CI/CD | Gitea Actions | Gitea 1.27.0 | Verify, test, build and publish on `main` |
| Package registry| Gitea generic registry | — | Storing published rule/gate bundles |
| Build tooling | GNU make + bash | — | `Makefile` targets wrapping the scripts |
| Hosting | Gitea self-hosted | `1.27.0` | Source control, CI runners, package registry (gitea.devegamoreno.com) |
## Justification
- **OPA + Rego**: standard, policy-as-code engine for authorization/gating; bundles are the
portable distribution unit; binary CLI avoids container runtime requirements.
- **Pinned OPA `v1.20.2`**: reproducible engine version locally and in CI via `scripts/install-opa.sh`
(no Docker), so tests and `opa build` see identical behaviour everywhere.
- **`rego.v1`**: canonical OPA 1.x syntax (import of `rego.v1`), future-proof and unambiguous.
- **Per-rule JSON Schemas**: `opa check --strict --schema` catches input/data type mistakes at
authoring time instead of runtime.
- **Separate evaluation / small rules**: each rule is an independent package+bundle with a small,
testable contract; consumers combine the results at runtime, enabling reuse across gates.
- **Changesets over npm workspaces**: each rule/gate is an npm package solely for versioning;
changesets links repository-level changes to published registry versions. `oxfmt` is used only
to format changelog markdown (there is no `prettier-plugin-rego` on npm), while Rego formatting
is enforced by `opa fmt` in CI.
- **Gitea generic registry**: stores arbitrary files (`.tar.gz` bundles) under
`/api/packages/{owner}/generic/{package}/{version}/{file}` without adding an external registry
dependency.
- **npm workspaces** (over pnpm/yarn): zero extra tooling; changesets v3 requires Node ≥ 22.11 and
npm ≥ 10.9, both met.
## Tools not used (and why)
- **Docker/containers**: excluded by design; OPA ships a static binary, so containers add
unnecessary runtime complexity for tests, checks and bundle builds.
- **prettier-plugin-rego**: does not exist on npm (verified 404); Rego formatting is
instead owned by `opa fmt`.
- **pnpm/yarn**: changesets supports them, but npm workspaces suffice since these packages are
private versioning shims, not published JS packages.
## Integration points
- **Gitea Actions** reads `secrets.GITEA_TOKEN` (scope `write:package`) and
`GITEA_OWNER`/`GITEA_URL`; publish job runs only on `main`.
- **`scripts/publish.sh`** uploads via `curl` to the generic registry; package names are
prefixed `rule-*` and `gate-*`.
- **Consumer contract**: bundles scope roots to `rules` so operators can supply
`data.deploygate.*` configuration separately and still have static schema checks apply.
## Environment (local dev machine)
- macOS (darwin/arm64), zsh
- Node.js `v24.18.0`, npm `11.16.0`
- git `2.50.1`, GNU make
- `tools/opa` (OPA `v1.20.2` binary committed to the repo working tree via install script, not git)
- regal `v0.42.0` optional on `PATH`