docs: add adoption guide, security policy and code owners #25

Merged
KofTwentyTwo merged 1 commits from feature/adoption-standards-docs into develop 2026-10-12 10:30:48 +00:00
5 changed files with 187 additions and 2 deletions

No files matched your search

+3
View File
@@ -0,0 +1,3 @@
# Every path has an owner (K22-REPO-08). Add narrower rules below for areas that
# need a specific reviewer once the project has more than one maintainer.
* @KofTwentyTwo
+1 -1
View File
@@ -5,7 +5,7 @@ CircleCI orb that generates CI/CD pipeline configurations from a `.munitor.yml`
## Key Commands
```bash
make test # Run all tests (BATS)
make test-scripts # Script unit tests (bats tests for the .bats suites)
make pack # Pack orb YAML from src/
make all # lint + pack + test
make validate # Validate packed orb with CircleCI CLI
+8
View File
@@ -1,5 +1,13 @@
# Contributing to Munitor
## Workflow
- **Branches.** Branch `feature/<name>` or `hotfix/<name>` from `develop` and open a pull request back to `develop`. Releases go through `release/X.Y.Z` into `main`; pushing the `vX.Y.Z` tag publishes `kof22/munitor@X.Y.Z`, and every push to `develop` or `feature/*` publishes `dev:snapshot`. Back-merge `main` into `develop` after a release.
- **Commits.** Conventional Commits (`feat(#N): ...`, `fix: ...`, `docs: ...`), signed (`git commit -S`), with a Developer Certificate of Origin sign-off line (`git commit -s`, which adds `Signed-off-by: Name <email>`). Reference the GitHub issue (`Closes #N`) where there is one.
- **Checks.** Run `make all` (yamllint, shellcheck, pack plus `circleci orb validate`, script and template tests) and `bats tests` (the `.bats` suites) before pushing. CircleCI runs only the orb-tools lint, pack and review jobs; the script, template and BATS tests run locally, so a green CI run does not replace them.
- **Security.** Report vulnerabilities privately as described in [SECURITY.md](SECURITY.md), never in a public issue.
- **AI assistance.** Disclose AI-assisted changes in the pull request description.
## Module Inventory
Munitor organizes CI/CD pipelines into **modules** (called "pipeline types" in `.munitor.yml`). Each module is a self-contained set of templates, jobs, commands, and scripts that handle a specific application stack.
+119 -1
View File
@@ -2,6 +2,14 @@
Latin: *munitor* (fortifier, protector) -- KofTwentyTwo's unified CircleCI orb for building, testing, and deploying all repositories. Pipeline changes happen in one place instead of 80+ repos.
| | |
| --- | --- |
| **Tier** | Internal until classified -- listed under *Awaiting classification* in the KofTwentyTwo standards [MAINTAINERS.md](https://github.com/KofTwentyTwo/standards/blob/main/MAINTAINERS.md); Product-tier requirements are being adopted |
| **Standards** | Targets [KofTwentyTwo standards](https://github.com/KofTwentyTwo/standards) 1.0.0 |
| **Orb** | [`kof22/munitor`](https://circleci.com/developer/orbs/orb/kof22/munitor), latest stable `0.3.3` |
| **Security** | [SECURITY.md](SECURITY.md) |
| **Contributing** | [CONTRIBUTING.md](CONTRIBUTING.md) |
## How It Works
Munitor uses CircleCI's [dynamic configuration](https://circleci.com/docs/dynamic-config/) to generate your full CI/CD pipeline at runtime. Each repo has a minimal `.circleci/config.yml` that triggers Munitor, and a `.munitor.yml` that declares what your project needs. Munitor reads your config, selects the right template, and generates a complete CircleCI workflow.
@@ -58,6 +66,93 @@ Munitor validates branch names and will fail on non-conforming names.
| `sonarcloud` | `SONAR_TOKEN` | SonarCloud analysis |
| `nvd` | `NVD_API_KEY` | OWASP dependency check (Java only, optional) |
## Adopting in another app
Munitor is a public CircleCI orb: any CircleCI organization can use it without forking. This checklist covers what a new consumer needs, for example a Java/Maven service such as me-health-portal.
**Version.** Use `kof22/munitor@0.3.3` (or `@0.3` to float on the 0.3 line) in `.circleci/config.yml`, and the same value as `orb_version` in `.munitor.yml`. Keep the setup orb and the generated pipeline on the same line.
### 1. Repository files
- `.circleci/config.yml`: the setup config from [Quick Start](#quick-start), pinned to `kof22/munitor@0.3.3`.
- `.munitor.yml`: pick a [pipeline type](#pipeline-types). A Java service is `java-webapp`. KofTwentyTwo's Website-Backend is a working example; a generalized version:
```yaml
pipeline: java-webapp
orb_version: "0.3.3"
image_name: my-service
java_version: "21"
docker:
registry: ghcr.io/my-org # the org default is ghcr.io/KofTwentyTwo -- always set this
cd:
repo: my-org/my-gitops-repo # omit to skip GitOps write-back
format: kustomize # default is helm (image.tag in values.yaml)
path: apps/my-service/kustomization.yaml # optional explicit file in a consolidated repo
production_only: true # only main updates the GitOps repo
supplemental_images: # optional extra images built from the same commit and version
- name: migrations
dockerfile: docker/Dockerfile.migrations
cd:
image_name: ghcr.io/my-org/my-service-migrations
health:
path: /health
port: "8000"
db: "true" # start a PostgreSQL sidecar for the health gate
migrations: migrations # run the <image>-migrations image against it first
smoke_paths: [/health]
sonar:
project_key: my-org_my-service # omit to skip SonarCloud
contexts:
registry: ghcr
github: github
sonar: sonarcloud # required only with sonar.project_key
nvd: nvd # optional
org: # organization defaults (see Known limitations)
ci_email: ci@example.com
ci_name: My CI
```
- A health endpoint that returns HTTP 200 within 30 seconds of container start (see [Health Check Requirement](#health-check-requirement)).
- A Dockerfile only for `node-webapp` (`docker.use_repo_dockerfile: true`) or for `supplemental_images`; `java-webapp` and `node-api` generate theirs.
### 2. CircleCI project settings
See [Prerequisites](#prerequisites): enable dynamic config (setup workflows) and allow uncertified orbs in the consuming organization.
### 3. Contexts and secrets
CircleCI organization contexts; the context names are set through `contexts.*`.
| Context | Variables | Needed for |
| --- | --- | --- |
| registry (e.g. `ghcr`) | `GHCR_USERNAME`, `GHCR_TOKEN` (`write:packages`) | Pushing images and inspecting existing tags; the immutable-tag guard fails closed without registry access |
| github | `GITHUB_TOKEN` with contents write on the app repository and on the GitOps repository | Reserving `vX.Y.Z` tags on `main` (required by `production`), GitHub Releases, GitOps write-back |
| sonar (optional) | `SONAR_TOKEN`; SonarCloud organization from `SONAR_ORG` (default `KofTwentyTwo`) | SonarCloud analysis |
| nvd (optional) | `NVD_API_KEY` | OWASP dependency check; `owasp: false` disables the check |
### 4. Branch model
Branch names are enforced: `main`, `develop`, `staging`, `feature/*`, `release/*`, `hotfix/*`. A merge to `main` is a production release: it reserves the next `vX.Y.Z` tag, pushes the image, updates the GitOps repository and creates the GitHub Release. Protect `main` accordingly.
### 5. Deployment infrastructure (outside Munitor)
Munitor stops at the GitOps commit. The consumer provides:
- a GitOps repository whose `kustomization.yaml` (an `images[]` entry named `<registry>/<image_name>`) or Helm `values.yaml` (`image.tag`) Munitor edits;
- Argo CD (or another controller) syncing that repository, with pull access to the registry;
- the runtime database and its backups. KofTwentyTwo's website uses a CloudNativePG cluster with an object-store backup and a `ScheduledBackup`, declared in `KofTwentyTwo/cluster-gitops` (`tenants/kof22/website`). Munitor only starts a throwaway PostgreSQL sidecar for the CI health gate and never touches a real database;
- schema migrations. Either the application migrates at start-up, or the deployment runs the `migrations` supplemental image (the KofTwentyTwo website runs a pre-migration backup image and then the migrations image as init containers). `health.migrations` only exercises that image in CI.
### 6. Known limitations
- Organization defaults point at KofTwentyTwo: registry `ghcr.io/KofTwentyTwo`, npm scope `@koftwentytwo`, CI email `munitor-ci@koftwentytwo.com`, SonarCloud organization `KofTwentyTwo`. Set `docker.registry`, the `org.*` keys and `SONAR_ORG` explicitly. The `org` block is read, but the unknown-key check prints a harmless `Unknown key 'org'` warning.
- `production` builds on `main` skip the quality gates, which run on `release/*` and `hotfix/*` pull requests. Do not merge unreviewed branches straight to `main`.
- CircleCI only; there is no GitHub Actions equivalent. Docker jobs use machine executors.
### 7. Upgrade notes
`0.3.3` reserves release tags atomically on `main` (needs the github context on `build-and-test`, which generated `production` workflows include), refuses to overwrite a version image tag built from another commit, and checks tag ownership before the GitOps bump. A consumer moving from a Munitor-derived orb with a tag-driven production trigger should compare that model with Munitor's merge-to-`main` model before switching.
## Pipeline Types
### `node-api`
@@ -475,7 +570,7 @@ Tags follow the format `vX.Y.Z` (git tag) and `X.Y.Z` (Docker tag). Tags are imm
| Field | Type | Default | Pipelines | Description |
|-------|------|---------|-----------|-------------|
| `pipeline` | string | *required* | all | Pipeline type: `node-api`, `node-webapp`, `java-webapp`, `terraform`, `sdk-distribution`, `validate-cd-repo`, `argocd-apps` |
| `orb_version` | string | *required* | all | Orb version for the generated pipeline (e.g., `1`, `dev:snapshot`) |
| `orb_version` | string | *required* | all | Orb version for the generated pipeline (e.g., `"0.3.3"`, `"0.3"`, `dev:snapshot`) |
| `image_name` | string | *required** | node-api, node-webapp, java-webapp | Docker image name (without registry prefix) |
| `node_version` | string | `20` | node-api, node-webapp | Node.js major version |
| `java_version` | string | `21` | java-webapp | Java major version |
@@ -486,6 +581,17 @@ Tags follow the format `vX.Y.Z` (git tag) and `X.Y.Z` (Docker tag). Tags are imm
| `cd.path` | string | -- | node-api, node-webapp, java-webapp | Explicit repository-relative `kustomization.yaml` path for consolidated GitOps repositories |
| `cd.production_only` | bool | `false` | node-api, node-webapp, java-webapp | Disable CD write-back from develop, staging, and release workflows |
| `cd.env.release` | string | `staging` | node-api, node-webapp, java-webapp | CD target environment for release branches |
| `cd.env.develop` / `cd.env.staging` / `cd.env.prod` | string | `develop` / `staging` / `prod` | node-api, node-webapp, java-webapp | CD target environment names for the develop, staging and main workflows |
| `cd.format` | string | `helm` | node-api, node-webapp, java-webapp | `helm` (sets `image.tag` in `values.yaml`, per environment under `environments/<env>/` when present) or `kustomize` (sets `images[].newTag`) |
| `server_module` | string | -- | gradle-webapp | Gradle module whose `build/libs` JAR goes into the generated image (multi-module builds) |
| `owasp` | bool | `true` | java-webapp | Run the OWASP dependency check |
| `package_manager` | string | `npm` | node-api, node-webapp | `npm` or `pnpm` |
| `supplemental_images` | list | `[]` | node-api, node-webapp, java-webapp | Extra images (`name`, `dockerfile`, `cd.image_name`) built and tagged with the same version |
| `health.db` | bool | `false` | node-api, node-webapp, java-webapp | Start a PostgreSQL sidecar for the health check |
| `health.migrations` | string | -- | node-api, node-webapp, java-webapp | Supplemental image suffix run against the sidecar before the health check |
| `health.smoke_paths` | list | `[]` | node-api, node-webapp, java-webapp | Extra paths that must return HTTP 200 during the health check |
| `test.coverage.summary_path` | string | `coverage/coverage-summary.json` | node-api, node-webapp | Coverage summary file read by the coverage gate |
| `org.docker_registry` / `org.npm_scope` / `org.ci_email` / `org.ci_name` / `org.orb_slug` | string | KofTwentyTwo values | all | Organization defaults; see [Adopting in another app](#adopting-in-another-app) |
| `coverage.min_instruction` | int | `70` | node-api, node-webapp, java-webapp | Minimum coverage percentage |
| `e2e` | bool | `false` | node-api, node-webapp, java-webapp | Enable Playwright E2E tests |
| `sbom` | bool | `false` | node-api, node-webapp, java-webapp | Enable SBOM generation |
@@ -596,3 +702,15 @@ excepted version. Audit errors, unknown chains and expired exceptions fail. A ne
upstream package release also fails and requires review. Trivy remains unchanged.
This mechanism requires npm audit report version 2 and a package-path lockfile;
unsupported reports fail. BATS and Node are required for the audit regression tests.
## Security
Report vulnerabilities privately; see [SECURITY.md](SECURITY.md).
## Contributing
See [CONTRIBUTING.md](CONTRIBUTING.md).
## License
[GPL-3.0](LICENSE)
+56
View File
@@ -0,0 +1,56 @@
# Security Policy
## Reporting a vulnerability
**Do not open a public issue for a security problem.**
Report it privately through GitHub's
[private vulnerability reporting](https://github.com/KofTwentyTwo/Munitor/security/advisories/new)
(the repository's **Security** tab, then **Report a vulnerability**). If that form is
unavailable, contact the maintainer privately through GitHub before disclosing anything.
Security contact: **James Maes** ([@KofTwentyTwo](https://github.com/KofTwentyTwo)),
maintainer.
Please include the affected orb version, the `.munitor.yml` pipeline type, how to
reproduce it, and the impact you see. Never include secrets or CircleCI context values.
## What to expect
KofTwentyTwo follows coordinated vulnerability disclosure. Timeframes are counted
from the day the report arrives and come from the
[KofTwentyTwo security program](https://github.com/KofTwentyTwo/standards/blob/main/policies/security-program.md):
| Step | Target |
| --- | --- |
| Acknowledge the report | 7 days |
| Assess it: confirm or reject, with a severity | 14 days |
| Release a fix for a CRITICAL vulnerability | 7 days |
| Release a fix for a HIGH vulnerability | 30 days |
| Release a fix for a MEDIUM vulnerability | 90 days |
| Release a fix for a LOW vulnerability | The next release |
| Publish the advisory (GitHub Security Advisory, CVE where applicable) | When the fix ships, or 90 days after the report, whichever comes first |
Reporters are credited in the advisory unless they ask not to be.
## Supported versions
| Version | Security fixes |
| --- | --- |
| 0.3.x (`kof22/munitor@0.3`) | Yes |
| Older | No; upgrade to the latest release |
Only the latest minor line receives fixes; a line ends when the next minor version is
published to the CircleCI orb registry.
## Scope notes
Munitor runs inside the consumer's CircleCI project with the consumer's contexts
(registry, GitHub, SonarCloud, NVD). Issues that let a generated pipeline leak context
secrets, push an image or GitOps change for the wrong commit, or bypass a security
gate are in scope.
## Published vulnerabilities
Fixed vulnerabilities are published as
[GitHub Security Advisories](https://github.com/KofTwentyTwo/Munitor/security/advisories).