Repository navigation
fix(security): secure defaults for the chart, the stores and tenants - #424
Merged
Merged
Conversation
Three changes from the security list of 10 November, each with its own section under 1.39.4 in UPGRADING. A default Helm install now runs the production profile with its NetworkPolicies on. backend.env defaulted to demo, so a release nobody configured served the API and ingest unauthenticated to the whole cluster. The backend refuses to start in production without an API credential and an ingest secret, so the chart now refuses to render until it knows their source - secrets.generate, secrets.existingSecret, or auth.* with ingest.hmacSecret - or until backend.env=demo is asked for by name, as the SSO demo values now do. CI lints both profiles and checks that a default render stops and that every way out renders. The kind installs run the new default with generated credentials, and check that the API and ingest refuse a caller without them and accept the generated ones (the probes sign v2), that NATS refuses a pod the NetworkPolicy admits, and that no other pod reaches it. With STORE_ENCRYPTION_KEY set, the governance stores and the audit log read a record the key had not sealed, so that stores written before the key stayed readable. That let anyone who could write to the volume add a suppression, or rewrite the audit chain, whose hashes carry no key. Such a record is now refused (cryptostore.ErrPlaintext), while a blob cut inside the sealed prefix is still a torn write. What predates the key is sealed once by `perspectivegraph seal-stores` (-dry-run lists it) or by one start with STORE_SEAL_EXISTING=true (Helm: crypto.sealExisting); an audit chain is verified before it is sealed. A tenant now has one spelling past authentication. Tokens, OIDC claims and ingest signatures normalize it (internal/tenant), the governance stores normalize what they are handed, and records written under a token's spelling are re-keyed: on load in the file stores, at startup in Postgres (pgmigrate.NormalizeTenants). For a tenant such as Acme-Corp the verdicts were split: the analyzer's calibration trend and the KEV holdout used the normalized name, the API the token's. Measured with Go 1.27.4: build, vet and test pass, the Postgres suites pass against a database and library coverage is 83.4%; govulncheck, gosec and staticcheck are clean; scripts/chart-install.sh passes on kind v1.36.1 with the bundled database, CloudNativePG and the Kubernetes connector. BEHAVIOUR CHANGE: a helm install or upgrade with backend.env at its default runs the production profile and does not render without a credential source; networkPolicy.enabled defaults to true. With STORE_ENCRYPTION_KEY set the engine refuses a record the key did not seal, until seal-stores seals what predates it. Tenant names are normalized past authentication, in /auth/me and new audit records too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Luigi Iacuaniello <luigi@a3thinker.it>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three changes from the security list of 10 November, each with its own section under 1.39.4 in UPGRADING.
A default Helm install now runs the production profile with its NetworkPolicies on. backend.env defaulted to demo, so a release nobody configured served the API and ingest unauthenticated to the whole cluster. The backend refuses to start in production without an API credential and an ingest secret, so the chart now refuses to render until it knows their source - secrets.generate, secrets.existingSecret, or auth.* with ingest.hmacSecret - or until backend.env=demo is asked for by name, as the SSO demo values now do. CI lints both profiles and checks that a default render stops and that every way out renders. The kind installs run the new default with generated credentials, and check that the API and ingest refuse a caller without them and accept the generated ones (the probes sign v2), that NATS refuses a pod the NetworkPolicy admits, and that no other pod reaches it.
With STORE_ENCRYPTION_KEY set, the governance stores and the audit log read a record the key had not sealed, so that stores written before the key stayed readable. That let anyone who could write to the volume add a suppression, or rewrite the audit chain, whose hashes carry no key. Such a record is now refused (cryptostore.ErrPlaintext), while a blob cut inside the sealed prefix is still a torn write. What predates the key is sealed once by
perspectivegraph seal-stores(-dry-run lists it) or by one start with STORE_SEAL_EXISTING=true (Helm: crypto.sealExisting); an audit chain is verified before it is sealed.A tenant now has one spelling past authentication. Tokens, OIDC claims and ingest signatures normalize it (internal/tenant), the governance stores normalize what they are handed, and records written under a token's spelling are re-keyed: on load in the file stores, at startup in Postgres (pgmigrate.NormalizeTenants). For a tenant such as Acme-Corp the verdicts were split: the analyzer's calibration trend and the KEV holdout used the normalized name, the API the token's.
Measured with Go 1.27.4: build, vet and test pass, the Postgres suites pass against a database and library coverage is 83.4%; govulncheck, gosec and staticcheck are clean; scripts/chart-install.sh passes on kind v1.36.1 with the bundled database, CloudNativePG and the Kubernetes connector.
BEHAVIOUR CHANGE: a helm install or upgrade with backend.env at its default runs the production profile and does not render without a credential source; networkPolicy.enabled defaults to true. With STORE_ENCRYPTION_KEY set the engine refuses a record the key did not seal, until seal-stores seals what predates it. Tenant names are normalized past authentication, in /auth/me and new audit records too.
What & why
What does this change, and why? Link any issue (
Closes #123).Checklist
feat:,fix:,docs:, …)gofmt,go vet,go test ./..., andgosecare clean(CI runs them;
make testlocally)tsc,npm run build, andvitestpassdocs/manual/(the README only if the first screen changes),
.env.exampleanddocs/perspectivegraph.postman_collection.jsongitleaksgate enforces it)at-rest encryption, export signing)
How was it verified?
Tests added/updated, manual steps, or a
make seed/make demorun - whateverproves it works.