Coming soon: Sign container images with Notation CLI using Notation plugin (recommended)
This Notation plugin (notation-digicert-stm) lets you sign and verify OCI container images using keys stored securely in DigiCert® Software Trust Manager.
Your private keys never leave DigiCert’s HSM. All cryptographic operations happen inside DigiCert’s cloud.
This plugin connects the Notation CLI to the Software Trust Manager API and supports:
JWS and COSE signature formats
RFC 3161 timestamping (optional)
Full certificate chain and revocation validation
Use this plugin if you need to:
Sign container images using centrally managed keys
Enforce supply chain security policies
Keep private keys inside a cloud HSM
Integrate signing into CI/CD pipelines
The plugin implements the Notation Plugin Framework v1 and exposes four capabilities to Notation:
Capability | Description |
|---|---|
SIGNATURE_GENERATOR.RAW | Plugin generates a raw cryptographic signature. Notation CLI wraps it in the envelope and handles timestamping. |
SIGNATURE_GENERATOR.ENVELOPE | Plugin generates the complete signature envelope (JWS or COSE), including all headers and certificate chain. |
SIGNATURE_VERIFIER.TRUSTED_IDENTITY | Plugin verifies that the signing certificate is trusted by STM. |
SIGNATURE_VERIFIER.REVOCATION_CHECK | Plugin checks that the signing certificate has not been revoked. |
Notation selects the appropriate mode automatically. In both modes, the private key remains in the STM cloud HSM.
Insecure / Private Registries
If your registry uses HTTP or a self-signed TLS certificate, add it to Notation's config.json so Notation does not reject the connection.
Config file location:
Platform | Path |
|---|---|
Windows |
|
Linux and macOS |
|
Add the registry to insecureRegistries:
{
"insecureRegistries": [
"localhost:5000",
"registry.internal.mycompany.com"
]
}Tip
For TLS-secured private registries with a self-signed certificate, add the CA to your OS trust store instead. Avoid insecureRegistries in production environments.
Trust policy
The trust policy specifies which registries to trust, which CA or identity must have signed the artifact, and what level of verification to enforce.
Trust policy file location:
Platform | Path |
|---|---|
Windows |
|
Linux and macOS |
|
Production policy (strict — recommended)
Enforces full chain verification, identity matching, and revocation checking. Replace values in angle brackets with your own.
{
"version": "1.0",
"trustPolicies": [
{
"name": "stm-production-policy",
"registryScopes": [
"registry.example.com/myteam/myapp"
],
"signatureVerification": {
"level": "strict"
},
"trustStores": [
"ca:digicert-stm-ca"
],
"trustedIdentities": [
"x509.subject: CN=My Signing Cert, O=My Org, C=US"
]
}
]
}Tip
trustedIdentities: Must match the Subject field of the signing certificate exactly, in comma-separated RFC 4514 DN format. Use notation inspect on a signed image to find the exact subject string (see Section 8).
For strict or permissive verification, Notation must trust the CA that issued the signing certificate.
Obtain the PEM CA certificate from your Software Trust Manager account or PKI administrator.
Save the certificate as
digicert-stm-ca.pem.Add it to Notation's trust store:
Verify the certificate was added:
notation cert list
Expected output:
STORE TYPE STORE NAME CERT NAME ca digicert-stm-ca digicert-stm-ca.pem
[Optional]: Add a Timestamp Authority (TSA) root certificate:
If you use
--timestamp-urlwhen signing, trust the TSA's root CA too:notation cert add \ --type tsa \ --store my-tsa-root \ tsa-root-ca.pem
Rreference both in the trust policy:
"trustStores": [ "ca:digicert-stm-ca", "tsa:my-tsa-root" ], "signatureVerification": { "level": "strict", "override": { "authenticTimestamp": "enforced" } }
Ensure the image is already pushed to your registry.
Find your keypair alias
You can locate the keypair alias via DigiCert® Software Trust Manager or Signing Manager Controller (SMCTL).
Sign the image
Notation resolves the tag to a content-addressable digest and signs that digest.
Sign using an alias (recommended)
notation sign \ --plugin digicert-stm \ --id <key-alias> \ <registry>/<repository>:<tag>
Sign using a keypair UUID
notation sign \ --plugin digicert-stm \ --id 3f46a2c1-8b9d-4e72-a3f1-0123456789ab \ registry.example.com/myapp:v1.0.0
Select a signature format
Notation supports two envelope formats:
JSON Web Signature (JWS)
CBOR Object Signing and Encryption (COSE)
Tip
Use COSE if your downstream tooling or policy requires it; otherwise JWS is widely supported.
Sign with a Timestamp Authority
Embedding an RFC 3161 timestamp means signatures remain verifiable even after the signing certificate expires.
notation sign \ --plugin digicert-stm \ --id my-rsa-4096-key \ --timestamp-url http://timestamp.digicert.com \ --timestamp-root-cert tsa-root-ca.pem \ registry.example.com/myapp:v1.0.0
Commonly used TSA endpoints:
Provider | URL |
|---|---|
DigiCert | http://timestamp.digicert.com |
Microsoft | http://timestamp.acs.microsoft.con |
GlobalSign | http://timestamp.globalsign.com/scripts/timstamp.dll |
Tip
When using a timestamp, you must also trust the TSA's root CA in your trust store and reference it in the trust policy.
Inspect and list signatures
Inspect a signature's metadata
notation inspect registry.example.com/myapp:v1.0.0
This shows the complete signature details:
registry.example.com/myapp@sha256:8637808eae0e7c2a...
└── application/jose+json
├── digest: sha256:3e4c5f6d...
├── signature algorithm: RSASSA-PSS-SHA-256
├── signed attributes
│ ├── content type: application/vnd.cncf.notary.payload.v1+json
│ └── signing time: Fri Mar 20 10:15:23 2026
└── certificate chain
├── SHA256 fingerprint: 4a:5b:6c:...
│ issued to: CN=My Signing Cert, O=My Org, C=US
│ issued by: CN=DigiCert STM CA, O=DigiCert, C=US
│ expiry: Sat Mar 20 10:15:23 2027
└── ...Use the issued to value verbatim as the trustedIdentities entry in your trust policy.
List all signatures on an artifact
notation list registry.example.com/myapp:v1.0.0
Output:
registry.example.com/myapp@sha256:8637808eae0e7c2a...
└── application/jose+json
└── sha256:3e4c5f6d...Plugin capabilities
Supported key types
Algorithm | Key sizes | Notes |
|---|---|---|
RSA | 2048, 3072, 4096 bit | Maps to RSASSA-PSS-SHA-{256,384,512} |
ECDSA | P-256, P-384, P-521 | Maps to ECDSA-SHA-{256,384,512} |
Tip
Ed25519 and ML-DSA are not yet mapped to Notation key specs because the Notation specification does not currently define specs for those algorithms. If you need post-quantum signing for container images, contact DigiCert support.
Key spec to algorithm mapping (automatic)
The plugin selects the optimal signature algorithm based on the keypair's key type and size:
Key type | Key size | Notation key spec | Signature algorithm |
|---|---|---|---|
RSA | 2048 | RSA_2048 | RSASSA-PSS-SHA-256 |
RSA | 3072 | RSA_3072 | RSASSA-PSS-SHA-384 |
RSA | 4096 | RSA_4096 | RSASSA-PSS-SHA-512 |
ECDSA | P-256 | EC_256 | ECDSA-SHA-256 |
ECDSA | P-384 | EC_384 | ECDSA-SHA-384 |
ECDSA | P-521 | EC_521 | ECDSA-SHA-512 |
You do not need to specify the algorithm — Notation queries the plugin via describe-key and determines the appropriate algorithm automatically.
Plugin not found by notation
Error
plugin "digicert-stm" not found
Solution
Run:
notation plugin list
Verify the binary is in the correct directory:
Windows:
dir $env:APPDATA\notation\plugins\digicert-stm\Linux/macOS:
ls ~/.config/notation/plugins/digicert-stm/
On Linux/macOS, to confirm the binary is executable, run:
chmod +x notation-digicert-stm
The binary name must be exactly
notation-digicert-stm(ornotation-digicert-stm.exeon Windows); Notation derives the plugin name from the binary name.
Authentication failures in plugin logs
Error
failed to setup STM client
or
401 Unauthorized
Solution
Confirm all four required env vars are exported in the same shell session where you run:
notation sign
Verify the certificate password:
openssl pkcs12 -info -in $SM_CLIENT_CERT_FILE -passin env:SM_CLIENT_CERT_PASSWORD
The API key must have
signingandView certificatepermissions in Software Trust Manager.
Keypair not found
Error
failed to get keypair: 404 Not Found
Solution
Run:
smctl keypair list
Tip
Aliases are case-sensitive.
Trust policy rejects the signature
Error
signature verification failed: no applicable trust policy
or
trusted identity did not match
Solution
Run:
notation inspect <image-ref>
Copy the exact certificate subject string.
Paste it verbatim into
trustedIdentitiesin your trust policy, prefixed withx509.subject:.Confirm the registry scope in
registryScopesmatches the image reference exactly. Partial wildcards (registry.example.com/*) are not valid — use"*"for global scope or a full repository path.Verify the CA cert is in the trust store:
notation cert list
Signature verification fails after certificate expiry
Use a Timestamp Authority (TSA) when signing. The embedded timestamp proves the signature was created while the certificate was valid, regardless of when verification occurs.
notation sign \ --plugin digicert-stm \ --id my-rsa-4096-key \ --timestamp-url http://timestamp.digicert.com \ --timestamp-root-cert tsa-root-ca.pem \ registry.example.com/myapp:v1.0.0
Enable debug logging
export SM_LOG_LEVEL=debug export SM_LOG_OUTPUT=stdout notation sign --plugin digicert-stm --id my-key registry.example.com/myapp:latest
Logs are also written to $SM_HOME/logs/sm-client.log by default.