ProudAuthDocs

Security checks and their exceptions#

Requirements: QA-002 (static and dependency checks with triaged exceptions), SEC-016 (supply-chain safeguards), DEP-003 (immutable, pinned artifacts). This page lists every automated check, what it covers, and every exception to it with its reason. An exception not listed here is a defect: report it like any other (CONTRIBUTING.md). Changes to this page need a security reviewer (.github/CODEOWNERS).

Checks#

CheckWhereCoversFails on
Build, go vet, gofmtCI job testAll Go codeAny error or unformatted file
Go tests against PostgreSQLCI job testUnit, contract and end-to-end tests, including TestRequirementsTraceability (every plan requirement has evidence, requirements-traceability.md) and TestReleaseToolchainPinnedAny failure
Fuzz smokeCI job test (15–30 s per target)Redirect matching and registration, email and domain canonicalization, duplicate JSON keys, policy definitions, trace headers, the egress policy, claim mappings; SDK verifier fuzzing is owned by the Go SDKA crash
Secret scanscripts/check-secrets.sh, CI job checksEvery tracked and untracked file except the exceptions belowPrivate keys, ProudAuth token formats, webhook secrets, cloud and chat tokens
License policyscripts/check-licenses.sh, CI job checksEvery Go module that provides a package to the binaries or their testsA module outside Apache-2.0, MIT, BSD-2/3-Clause, ISC or MPL-2.0, a module without a license file, or a module missing from the module cache
Vulnerability review (source)govulncheck ./..., CI job checksReachable vulnerabilities in Go code and its modulesAny reachable vulnerability
Vulnerability review (binaries)govulncheck -mode=binary, CI job image and the release workflowThe shipped binaries, every platform in a releaseAny vulnerability in the binary
Static analysisstaticcheck, CI job checksAll Go codeAny finding
Kubernetes manifestsmake k8s-validate, CI job checksdeploy/kubernetes rendersA render error
Independent SDK CIFive public SDK repositoriesGo race tests and verifier fuzzing; Node type checks, dependency audit and tests; Dart analysis, format and tests; PHP syntax/strict tests and Composer validation; .NET locked restore/build/tests/format/packages on three operating systemsAny check failure in the owning repository
SDK contract ownershipTestSDKRepositoryBoundariesNormal pinned Go module, successful immutable SDK CI snapshots and matching synthetic contract hashes (evidence)A local replacement, missing pipeline check, stale source/workflow metadata or mismatched fixture
Image smoke testCI job image (scripts/smoke-test.sh)The image starts read-only in the Compose stack: liveness, readiness, discovery, JWKS, and the password grant refusedAny failure
Contribution provenanceCI job dcoEvery commit of a pull request carries Signed-off-byA missing sign-off
Dependency updates.github/dependabot.yml; each SDK owns its update rulesService Go modules (including the pinned Go SDK), GitHub Actions, Docker base images; language dependency manifests in standalone SDKsReviewed pull requests, not a gate

Exceptions#

ExceptionScopeReasonCompensating controlRevisit when
Secret scan skips tests/, *_test.go, docs/, deploy/compose/secrets/Test fixtures, documentation examples, generated development secretsThese hold test-only keys and example values on purpose (fixtures say so in their README); scanning them would make the check permanently redCode review; deploy/compose/secrets/ is generated by init-secrets.sh and ignored by git; production configuration refuses literal secrets (Validate())A real secret is ever found in an excluded path
Shared contract fixture keys are excluded as test datatests/fixtures/sdk-contracts/The vectors pin signature behaviour; keys sign nothing realREADME marks every key test-only; pinned SDK snapshots check both JSON fixture hashesA fixture gains real operational data or keys
npm audit fails only on high and criticalIndependent proudauth-sdk-nodeThe SDK has no runtime dependencies; advisories affect TypeScript and type packages used to build and testDependency-update reviews; low and moderate advisories are reviewed thereThe SDK gains a runtime dependency
No automated license check for npm, pub and Composer dependenciesIndependent Node, Dart and PHP SDK repositoriesNode.js and PHP have no runtime dependencies; Dart's are crypto and http (BSD-3-Clause, Dart team)Dependency changes are reviewed in the owning SDK repositoryAny SDK gains a runtime dependency
No dedicated vulnerability scanner for Dart and PHP in CIIndependent Dart and PHP SDK repositoriesPHP has none; Dart dependencies receive advisory/update reviewOwning SDK dependency alerts and pull requestsEither SDK gains further runtime dependencies
No static analyser for PHP beyond php -lIndependent proudauth-sdk-phpNo additional PHP analysis tool is pinned yetdeclare(strict_types=1); warnings/deprecations fail tests on PHP 8.2 and 8.5Before a PHP package registry release
CI does not scan the image's OS layergcr.io/distroless/static-debian12:nonrootThe base has no package manager or shell; the binaries are staticThe local Grype profile below found zero OS-package matches; release SBOM attestations and Dependabot retain their separate controlsBefore each release

Base-image pins — 2026-10-13#

The Dockerfile's two base images now carry immutable OCI index digests (DEP-003, SEC-016), read from locally cached Docker image descriptors:

BaseSHA-256 index digest
golang:1.27.2-trixiee58d6f83b3416618d8bcac2b3dde1b7f7e3c4a77d25e88637f8bbae81536c48d
gcr.io/distroless/static-debian12:nonrootafa5c872c891853ca7fcf1f12c3edb23f7eeef36189728842dd51042ff57f7ab

The cached builder reports GOLANG_VERSION=1.27.2, matching the release workflow; both descriptors are OCI indexes. No registry lookup or image download was used. TestReleaseToolchainPinned checks version alignment and immutable base references. Pinning is not a current vulnerability scan, an image build/smoke result or independent reproduction; those retain their separate gates. Dependabot should review digest updates with the version tags.

Two-OS binary reproduction — 2026-10-13#

The frozen development checkout now has a measured macOS/Linux binary reproduction profile (M0, DEP-003, SEC-016). All 12 release targets are byte-identical across the host and a separate Linux container, on both an initial run and an independent invocation of the final runner:

Target platformidentity-server SHA-256 prefixidentity-worker prefixidentity-cli prefixResult
Linux amd64930690b409fc9c76f1b85e77524969383118identical
Linux arm64fdfb3127b59c5c0ce64465d0fb2dc2452f54identical
Darwin amd64aa58d509e8b91aa40e4c71b4815b47083ca2identical
Darwin arm6435d29d799d46a1e1458b8fce6cc1afffd4cbidentical

Full hashes and comparison, frozen input manifest host toolchain, scoped verification and artifact hashes identify 504 source/input files, version dev-repro-20261013, and snapshot SHA-256 1f0e4064801707023be84691cb60db9a47369b46df80d3b15c3ba818ae49b89b. The final comparison completed at 2026-10-12T22:14:28.120724Z (2026-10-13 local time). identity-bench is outside this release target set.

Environment: Mac16,8 / Apple M4 Pro, 12 CPUs, 24 GiB, macOS 27.0.1 (26A434), Darwin 27.0.0; the Docker Desktop Linux VM shares the host. Both compilers report Go 1.27.2. The installed host Go remains 1.27.1; the runner bootstraps a temporary Darwin toolchain from the Go source in the pinned cached builder image. The Linux compiler is the image's supplied binary. The image reference/digest is the Go base above, with its untagged repository digest resolved locally. No tag, module or toolchain is downloaded. The two builders use separate writable caches and one frozen source tree; Linux mounts the populated module cache read-only and has network none. Proxy/sumdb/toolchain downloads are disabled before Go preflight. Caller workspaces, flags and experiments are cleared.

Flags match the release profile: CGO_ENABLED=0, GOAMD64=v1, GOARM64=v8.0, -mod=readonly -buildvcs=false -trimpath, and -ldflags="-s -w -buildid= -X main.version=dev-repro-20261013". The container, temporary SDK, both caches, input copy and all 24 built binaries are removed; only hashes and metadata remain.

Reproduce using the cached image and modules:

sh
REPRO_VERSION=dev-repro-20261013 \
  REPRO_OUT="$PWD/repro-results/private-run" make repro-local

REPRO_OUT must be fresh or empty. The executable orchestration regression checks an untagged cached digest, download/flag isolation, all 12 outputs, one deliberately different binary, wrong SDK/version refusals and owned resource cleanup. Three race repetitions pass (three top-level executions, 12 subtests, 6.527s); controlled compilers check the wrapper, while the published real builds establish byte equality. All 41 contract checks and 16 subtests pass (33.584s), with vet, formatting, shell/Make recipe, secret and license checks. Two evidence rows match the complete isolated preview; the protected traceability contract is unchanged. Earlier full-module checks retain their own build.

One physical host, two OS environments. This is a frozen development binary profile, not a tagged release, off-host/independent-organization build, container-image or archive reproduction, current vulnerability audit, provenance attestation or qualified security review. Release/package evidence and remaining supply-chain gates retain their own scope.

Current dependency and supply-chain checks — 2026-10-13#

Structured results record Go 1.27.2, Staticcheck 2026.2.2, govulncheck v1.8.0, source hashes and exact upstream references (QA-002, SEC-016, DEP-003):

CheckResult
Staticcheck on all Go packages and testsPass, zero findings after resolving 20 unused-code/style/deprecation findings
Go source vulnerability scanPass, zero reachable or imported-package findings
All 12 server/worker/CLI targets (Linux/macOS, amd64/arm64)Pass, all builds and symbol-bearing binary vulnerability scans
npm audit of the unchanged SDK lockPass, zero advisories in all severity categories
External workflow ActionsEight actions resolved to full commit SHAs; all 25 references pinned with their previous tag as a comment
Dockerfile frontenddocker/dockerfile:1@sha256:4edf897a3ffa55b89f906fc8cc78afdb3f1834cc9c7083565e611a8a7d5fe99e, verified against the registry manifest bytes

The prior Staticcheck 2025.1.1 pin fails to decode Go 1.27 export-data version 5. The tested stable 2026.2.2 release replaces it; CI's checks stay enabled. Contract checks reject floating action references and an unpinned Dockerfile frontend.

The canonical Go vulnerability database was downloaded for these checks; its modification time is 2026-10-08T22:31:09Z, with the zip's download time and hash recorded separately. Final source and binary scans use this frozen database explicitly through -db. Earlier HTTP scan output retains its separate scope.

Triage: GO-2026-5932 concerns the unmaintained OpenPGP packages in golang.org/x/crypto, with no known fixed version. It appears only at module level: none of those packages occurs in the current 498-package dependency graph, including tests, or any scanned binary. The required Argon2/bcrypt dependency remains; no scanner suppression is configured. Reassess this disposition if the dependency graph changes. These checks establish snapshot results. The local image and SBOM profile below adds artifact evidence; official signatures/provenance and publication retain their separate gates.

Local image and release preparation — 2026-10-13#

Frozen verification, image checks and asset hashes record development version dev-check-20261013-9e46df90789bcd6d on Go 1.27.2. The actual Dockerfile and its immutable references were used (SEC-016, DEP-003, DEP-004, DEP-017). Necessary scanner/build downloads were authorized; runtime checks used dedicated containers and a fresh database.

CheckResult
Linux arm64 image in production modePass: TLS with hostname verification, non-root UID/GID 65532, read-only root, all capabilities dropped, no new privileges
Image smokeLiveness/readiness/discovery/JWKS: 200; anonymous password grant: 401; implicit flow: 400; worker tasks: exit 0, no errors
Image's three symbol-bearing binary scansPass: zero reachable or imported-package findings
Image OS inventory with Grype 0.120.1Zero OS-package vulnerability matches; Debian 12 identified, database built 2026-10-12T06:45:22Z
Stripped binary buildsAll 12 server/worker/CLI targets build; all three Linux arm64 image binaries equal their host cross-builds
Source and image SBOMsSPDX 2.3: 166 source packages; 103 image packages including the image identity, 952 hashed files
Binary-only offline bundle582 internal file checksums verified, six Linux binaries match the release-profile builds, no local secret paths included

The source SBOM excludes local operational secrets and build output. The image SBOM records the final smoke-tested image. The Grype result contains three module-level GO-2026-5932 matches, one per stripped binary; the affected OpenPGP packages remain absent, as triaged above. No findings are suppressed. The scanned earlier image and final image have equal hashes for all 952 files and equal inventories of 102 package instances, with comparison evidence. Their manifest/config identities differ between local builds.

In the repository migration export, two personal cache-directory paths in the Syft catalogue's tool descriptor are redacted. Package/file inventory and image identity are unchanged; original source/image SPDX SBOM bytes are unchanged. Export provenance records the new catalogue and artifact-manifest hashes. No release signature or attestation is claimed to survive these changed metadata bytes.

The database uses PostgreSQL 18.6, shared_buffers=128MB, max_connections=80, 2 GiB tmpfs and a dedicated Docker network. Its postgres role and unencrypted database transport are local smoke fixtures; SMTP is configured but delivery and administrator sign-in are outside this image smoke. The recorded configuration uses file references and contains no secret values. This is one laptop and one image architecture.

Containers, images and newly created build-cache records are removed; all 868 pre-existing cache records remain. Temporary binaries/archives and private scanner caches are removed after verification. Hashes and SBOMs are retained. This is local preparation, not a published release: no commit/tag, upload, release signature or trusted provenance attestation was created. Unsigned BuildKit metadata is not a CI attestation (GOV-005).

Open items#

These are known gaps, not accepted exceptions:

  • Qualified independent security review has not happened. The review scope is ready. The owner excluded this condition from the 2026-10-13 delivery gate. Internal correctness tests and build reproduction establish their own evidence; no independent review has been performed or claimed.
  • Off-host release and image reproduction remain unverified. The two-OS development binary profile above is measured on one physical host; no independent machine/organization has reproduced an official release, container image or offline archive.
  • Historical release evidence remains snapshot-scoped. The local records above predate a version tag and do not establish hosted signatures or attestations. The owner subsequently authorized the public repository split and an initial prerelease. Every published version must pass the complete configured workflow; its actual binaries, images, SBOMs, signatures and hosted attestations are checked on the service's Releases page. SDK source publication and successful independent CI do not establish a package registry release or replace service release evidence.
ProudAuth · Self-hosted identityBuilt 2026-10-13 · d9cc813ae809 · content snapshot
⌕

Search all guides and the API contract.

↑ ↓ to navigate Enter to open · Esc to close