Security¶
Authentication¶
All API endpoints except health checks require a Bearer token:
curl -H "Authorization: Bearer YOUR_TOKEN" \
http://localhost:8080/v1/targets
Generate a strong token:
openssl rand -hex 32
Supply Chain Security¶
Every release image is signed and attested through a fully keyless pipeline - no long-lived private keys exist anywhere. The pipeline produces four independently verifiable artifacts. Full verification commands are documented in Release Process.
What is signed
Image signature via cosign (GitHub Actions OIDC, recorded in Rekor)
CycloneDX SBOM attached as a cosign attestation (
--type cyclonedx)Release-metadata attestation (digest, source commit, build timestamp)
SLSA L3 build provenance via
slsa-github-generatorin an isolated jobTUF metadata chain published to GitHub Pages via
tuf-on-ci
Verifying an image before deployment
All verification uses the image digest, not the tag. Resolve it first:
DIGEST=$(cosign verify \
--certificate-identity \
"https://github.com/amaanx86/oci-prometheus-sd-proxy/.github/workflows/docker-build-push.yml@refs/tags/v<version>" \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
ghcr.io/amaanx86/oci-prometheus-sd-proxy:<version> 2>/dev/null \
| python3 -c "
import json, sys
records = json.load(sys.stdin)
print(list({r['critical']['image']['docker-manifest-digest'] for r in records})[0])
")
IMAGE="ghcr.io/amaanx86/oci-prometheus-sd-proxy@${DIGEST}"
Image signature:
cosign verify "${IMAGE}" \
--certificate-identity \
"https://github.com/amaanx86/oci-prometheus-sd-proxy/.github/workflows/docker-build-push.yml@refs/tags/v<version>" \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
SLSA L3 provenance (requires slsa-verifier):
slsa-verifier verify-image "${IMAGE}" \
--source-uri "github.com/amaanx86/oci-prometheus-sd-proxy" \
--source-tag "v<version>"
See Release Process for SBOM attestation and release-metadata attestation verification.
TUF metadata repository
Release manifests are published independently at https://github.com/amaanx86/oci-prometheus-sd-proxy-tuf-on-ci. This keeps TUF lifecycle management (key rotation, metadata expiry) isolated from the application repository. The signed metadata is served via GitHub Pages at https://amaanx86.github.io/oci-prometheus-sd-proxy-tuf-on-ci/metadata/.
Best Practices¶
- Use environment variables
Never hardcode tokens in config.yaml. Use the
SERVER_TOKENenvironment variable instead.- Read-only volumes
Mount config.yaml and OCI keys as read-only:
-v /path/to/config.yaml:/etc/oci-sd/config.yaml:ro -v /path/to/keys:/etc/oci-sd/keys:ro
- Restrict key permissions
Keep OCI API keys with strict permissions:
chmod 600 oci-keys/api_key.pem
- Unencrypted keys
For automation, use unencrypted API keys. This simplifies deployment without compromising security (keys are read-only and not cached in memory beyond startup).
- Secrets management
In production, use a secrets manager: - AWS Secrets Manager - HashiCorp Vault - Kubernetes Secrets - GitHub Secrets
- Network isolation
Run the service in a private network. Only Prometheus servers should access the API.
- Monitor access
Enable logging and monitor API access patterns for suspicious activity.
Implementation Details¶
- Timing-safe token comparison
Uses
crypto/subtle.ConstantTimeCompare- not vulnerable to timing attacks.- Minimal runtime image
Uses distroless base image (
gcr.io/distroless/static-debian12:nonroot): - No shell - No package manager - Minimal attack surface- Key handling
Keys read at startup only
Not cached in memory beyond initial read
No sensitive data logged