Document version: v0.19.0 Audience: DevOps engineers, security teams, compliance officers
This document describes the OCI (Open Container Initiative) image labels used in the Secrets container image. These labels provide metadata for security scanning, SBOM generation, container registries, and operational tooling.
The Secrets container image follows the OCI Image Format Specification for image annotations. Labels are embedded at build time and provide essential metadata about the image's content, provenance, and security characteristics.
Use Cases:
-
Security Scanning: Tools like Trivy, Grype, and Snyk use labels to identify versions and vulnerabilities
-
SBOM Generation: Software Bill of Materials (SBOM) tools use labels for component tracking
-
Container Registries: Docker Hub, GitHub Container Registry, and others display label information
-
Operational Tooling: Monitoring tools and CI/CD pipelines use labels for automation
The image uses the standard org.opencontainers.image.* namespace defined by the OCI specification.
| Label | Description | Example Value | Source |
|---|---|---|---|
org.opencontainers.image.title |
Human-readable image title | Secrets |
Static |
org.opencontainers.image.description |
Brief description of the application | Lightweight secrets manager with envelope encryption, transit encryption, and audit logs |
Static |
org.opencontainers.image.url |
Project homepage URL | https://github.com/allisson/secrets |
Static |
org.opencontainers.image.source |
Source code repository URL | https://github.com/allisson/secrets |
Static |
org.opencontainers.image.documentation |
Documentation URL | https://github.com/allisson/secrets/tree/main/docs |
Static |
| Label | Description | Example Value | Source |
|---|---|---|---|
org.opencontainers.image.version |
Application version | v0.19.0 |
Build arg (VERSION) |
org.opencontainers.image.created |
ISO 8601 build timestamp | 2026-02-27T10:30:00Z |
Build arg (BUILD_DATE) |
org.opencontainers.image.revision |
Git commit hash | 23d48a137821f9428304e9929cf470adf8c3dee6 |
Build arg (COMMIT_SHA) |
Note: These labels are injected at build time via Docker build arguments. Local builds without build args will show default values (version=dev, created and revision empty).
| Label | Description | Example Value | Source |
|---|---|---|---|
org.opencontainers.image.licenses |
SPDX license identifier | MIT |
Static |
org.opencontainers.image.vendor |
Organization or individual name | Allisson Azevedo |
Static |
org.opencontainers.image.authors |
Contact information | Allisson Azevedo <allisson@gmail.com> |
Static |
| Label | Description | Example Value | Source |
|---|---|---|---|
org.opencontainers.image.base.name |
Base image name | gcr.io/distroless/static-debian13 |
Static |
org.opencontainers.image.base.digest |
Base image SHA256 digest | sha256:d90359c7a3ad67b3c11ca44fd5f3f5208cbef546f2e692b0dc3410a869de46bf |
Static |
Purpose: Base image metadata enables:
-
Supply Chain Security: Track the provenance of the base image
-
Vulnerability Scanning: Identify vulnerabilities in the base layer
-
SBOM Generation: Create complete software bill of materials
-
Immutable Builds: Verify that the expected base image was used
View all labels:
docker inspect allisson/secrets:latest | jq '.[0].Config.Labels'
View specific label:
docker inspect allisson/secrets:latest \
--format '{{ index .Config.Labels "org.opencontainers.image.version" }}'
View version information:
docker inspect allisson/secrets:latest | jq -r '
.[0].Config.Labels |
"Version: \(.["org.opencontainers.image.version"])
Build Date: \(.["org.opencontainers.image.created"])
Commit SHA: \(.["org.opencontainers.image.revision"])"
'
services:
secrets-api:
image: allisson/secrets:latest
# Labels are automatically inherited from the image
# You can also add container-specific labels:
labels:
- "com.mycompany.environment=production"
- "com.mycompany.team=platform"
Generate CycloneDX SBOM:
# Using Syft
syft allisson/secrets:latest -o cyclonedx-json > sbom.json
# Using Trivy
trivy image --format cyclonedx allisson/secrets:latest > sbom.json
Generate SPDX SBOM:
# Using Syft
syft allisson/secrets:latest -o spdx-json > sbom.spdx.json
# Using Trivy
trivy image --format spdx-json allisson/secrets:latest > sbom.spdx.json
The OCI labels provide metadata that enriches SBOM reports with:
-
Application name and version
-
Build timestamp and commit hash
-
Base image provenance
-
License information
-
Author and vendor details
Trivy scan with label context:
trivy image --severity HIGH,CRITICAL allisson/secrets:latest
# Trivy uses labels to:
# - Identify the application version for CVE correlation
# - Track base image vulnerabilities via base.name and base.digest
# - Generate detailed reports with build metadata
Grype scan with label context:
grype allisson/secrets:latest
# Grype uses labels to:
# - Match package versions against vulnerability databases
# - Track base image components
# - Provide remediation guidance based on version metadata
Docker Hub:
-
Labels appear under "Image Details"
-
Version, description, and source URL are prominently displayed
-
Automated builds can use labels for tagging strategies
GitHub Container Registry (ghcr.io):
-
Labels are displayed in the package details page
-
Source URL creates automatic linking to the repository
-
Version labels enable automated vulnerability alerts
AWS ECR / Google Artifact Registry:
-
Labels are indexed for searching and filtering
-
Lifecycle policies can use labels for retention rules
-
Security scanning services use labels for CVE tracking
# Build with version metadata
docker build -t allisson/secrets:<VERSION> \
--build-arg VERSION=v0.19.0 \
--build-arg BUILD_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
--build-arg COMMIT_SHA=$(git rev-parse HEAD) .
GitHub Actions (automatic injection):
- name: Build Docker image
run: |
VERSION=$(git describe --tags --always --dirty)
BUILD_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
COMMIT_SHA=${{ github.sha }}
docker build -t allisson/secrets:latest \
--build-arg VERSION=${VERSION} \
--build-arg BUILD_DATE=${BUILD_DATE} \
--build-arg COMMIT_SHA=${COMMIT_SHA} .
GitLab CI:
build:
script:
- export VERSION=$(git describe --tags --always --dirty)
- export BUILD_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
- export COMMIT_SHA=${CI_COMMIT_SHA}
- docker build -t allisson/secrets:latest
--build-arg VERSION=${VERSION}
--build-arg BUILD_DATE=${BUILD_DATE}
--build-arg COMMIT_SHA=${COMMIT_SHA} .
Makefile (using make docker-build):
# Automatic version detection and injection
VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo "dev")
BUILD_DATE := $(shell date -u +"%Y-%m-%dT%H:%M:%SZ")
COMMIT_SHA := $(shell git rev-parse HEAD 2>/dev/null || echo "unknown")
docker-build:
docker build -t $(DOCKER_IMAGE):latest \
--build-arg VERSION=$(VERSION) \
--build-arg BUILD_DATE=$(BUILD_DATE) \
--build-arg COMMIT_SHA=$(COMMIT_SHA) .
Create a script to verify that all required labels are present:
#!/bin/bash
# verify-oci-labels.sh
IMAGE="allisson/secrets:latest"
REQUIRED_LABELS=(
"org.opencontainers.image.title"
"org.opencontainers.image.description"
"org.opencontainers.image.version"
"org.opencontainers.image.created"
"org.opencontainers.image.revision"
"org.opencontainers.image.licenses"
"org.opencontainers.image.source"
"org.opencontainers.image.base.name"
"org.opencontainers.image.base.digest"
)
echo "Verifying OCI labels for: $IMAGE"
echo "============================================"
MISSING=0
for label in "${REQUIRED_LABELS[@]}"; do
value=$(docker inspect "$IMAGE" \
--format "{{ index .Config.Labels \"$label\" }}" 2>/dev/null)
if [ -z "$value" ] || [ "$value" = "<no value>" ]; then
echo "❌ MISSING: $label"
MISSING=$((MISSING + 1))
else
echo "✅ $label: $value"
fi
done
echo "============================================"
if [ $MISSING -eq 0 ]; then
echo "All required labels present"
exit 0
else
echo "Missing $MISSING required labels"
exit 1
fi
Add label verification to your CI/CD pipeline:
# .github/workflows/ci.yml
- name: Verify OCI labels
run: |
docker inspect allisson/secrets:latest | jq -e '
.[0].Config.Labels |
select(
.["org.opencontainers.image.version"] != null and
.["org.opencontainers.image.created"] != null and
.["org.opencontainers.image.revision"] != null and
.["org.opencontainers.image.licenses"] == "MIT"
)
' || (echo "Missing required OCI labels" && exit 1)
| Scenario | Labels to Update | Action |
|---|---|---|
| New release | version, created, revision |
Automatic (build args) |
| Base image update | base.name, base.digest |
Manual update in Dockerfile |
| License change | licenses |
Manual update in Dockerfile |
| Repository move | url, source, documentation |
Manual update in Dockerfile |
| Author change | authors, vendor |
Manual update in Dockerfile |
| Description change | title, description |
Manual update in Dockerfile |
When updating the distroless base image:
# 1. Pull the latest base image
docker pull gcr.io/distroless/static-debian13:latest
# 2. Get the SHA256 digest
docker inspect gcr.io/distroless/static-debian13:latest \
--format '{{index .RepoDigests 0}}'
# Output: gcr.io/distroless/static-debian13@sha256:d90359c7...
# 3. Update Dockerfile:
# - FROM statement with new digest
# - org.opencontainers.image.base.digest label with new digest
Bad (local builds without metadata):
docker build -t allisson/secrets:latest .
# Labels show: version=dev, created=<empty>, revision=<empty>
Good (production builds with metadata):
docker build -t allisson/secrets:latest \
--build-arg VERSION=$(git describe --tags) \
--build-arg BUILD_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
--build-arg COMMIT_SHA=$(git rev-parse HEAD) .
# Labels show: version=v0.19.0, created=2026-02-27T10:30:00Z, revision=23d48a1...
Add label verification to your pipeline to catch missing metadata:
# Fail the build if version is not set correctly
VERSION=$(docker inspect allisson/secrets:latest \
--format '{{ index .Config.Labels "org.opencontainers.image.version" }}')
if [ "$VERSION" = "dev" ] || [ -z "$VERSION" ]; then
echo "ERROR: Image version not set correctly"
exit 1
fi
Example: Automatic vulnerability scanning based on version:
# Scan only production releases (not dev builds)
VERSION=$(docker inspect "$IMAGE" \
--format '{{ index .Config.Labels "org.opencontainers.image.version" }}')
if [[ "$VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
trivy image --severity HIGH,CRITICAL "$IMAGE"
else
echo "Skipping scan for non-release build: $VERSION"
fi
Keep this documentation up-to-date when adding or removing labels. All label changes should be:
-
Documented in this file
-
Reviewed for compliance with OCI specification
-
Tested in CI/CD pipelines
-
Announced in release notes
Symptom: docker inspect shows empty labels
Cause: Build arguments not passed during build
Solution:
# Verify build arguments were passed
docker history allisson/secrets:latest | grep ARG
# Rebuild with build arguments
docker build -t allisson/secrets:latest \
--build-arg VERSION=v0.19.0 \
--build-arg BUILD_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ") \
--build-arg COMMIT_SHA=$(git rev-parse HEAD) .
Symptom: Labels show version=dev, created=<empty>, revision=<empty>
Cause: Build arguments were not provided (using default values from ARG statements)
Solution: Always provide build arguments in production builds (see "Build-Time Label Injection" section)
Symptom: Security scanner reports base image mismatch
Cause: Dockerfile FROM statement uses different digest than base.digest label
Solution:
# 1. Check actual base image digest
docker inspect allisson/secrets:latest \
--format '{{index .RootFS.Layers 0}}'
# 2. Verify it matches the label
docker inspect allisson/secrets:latest \
--format '{{ index .Config.Labels "org.opencontainers.image.base.digest" }}'
# 3. Update Dockerfile if they don't match
-
Dockerfile - Source of OCI labels
-
Container Security Guide - Security hardening and verification
-
Security Scanning Guide - Vulnerability scanning and SBOM generation
-
Multi-Architecture Builds - Building for multiple platforms
-
Docker Getting Started - Basic Docker usage