Module Signing and Verification
Timoni modules are distributed as OCI artifacts. When publishing a module version to a container registry, the OCI artifact can be cryptographically signed to improve the software supply chain security.
Cosign
Timoni can sign modules using Sigstore Cosign. Cosign is a tool that allows you to sign and verify OCI artifacts with a public/private key pair or with an OIDC token provided by GitHub, Google or Microsoft.
To sign modules, you need to install
the Cosign v2 binary and place it in the PATH
for Timoni to use it.
Sign with static keys
Generate a cosign key pair:
cosign generate-key-pair
Export the private key password with:
export COSIGN_PASSWORD=<your password>
Sign the module while pushing:
timoni mod push ./modules/my-app oci://ghcr.io/my-org/modules/my-app \
--version=1.0.0 \
--sign=cosign \
--cosign-key=cosign.key
Timoni will push the module to the registry and will pass the OCI artifact digest to Cosign. Cosign will push the signature to the registry and will record the signature in the Rekor transparency log.
To verify the module signature:
cosign verify ghcr.io/my-org/modules/my-app:1.0.0 --key=cosign.pub
To verify the module signature while pulling:
timoni mod pull oci://ghcr.io/my-org/modules/my-app -v 1.0.0 \
--output ./my-module \
--verify=cosign \
--cosign-key=cosign.pub
Sign with Cosign keyless
For keyless signing, the Cosign CLI would prompt you to confirm that your email will be stored
in the public transparency logs. Timoni adds --yes
to the cosign command to prevents this prompt.
Using Timoni with Cosign keyless signature means that users agree to this statement:
Note that there may be personally identifiable information associated with this signed artifact.
This may include the email address associated with the account with which you authenticate.
This information will be used for signing this artifact and will be stored in public transparency logs and cannot be removed later.
By typing 'y', you attest that you grant (or have permission to grant) and agree to have this information stored permanently in transparency logs.
Sign the module while pushing:
timoni mod push ./modules/my-app oci://ghcr.io/my-org/modules/my-app \
--version=1.0.0 \
--sign=cosign
Signing in CI
When using timoni push
in CI workflows, you can configure GitHub and
GitLab to provide Cosign with an OIDC token.
To automate the publishing and signing of module versions, please see the Timoni GitHub Actions.
To verify the module signature:
cosign verify ghcr.io/my-org/modules/my-app:1.0.0 \
--certificate-identity-regexp=<your email address> \
--certificate-oidc-issuer-regexp=<your issuer URL>
Verify Signature from GitHub action or GitLab CI/CD
When the signature was created in GitHub via the keyless signing you should set the flag --certificate-identity-regexp
to a value like ^https://github.com/<user|org>/<repo-name>.*
and set the flag --certificate-oidc-issuer-regexp
to https://token.actions.githubusercontent.com
.
GitLab is the same setup for the identity flag, https://gitlab.com
instead of https://github.com
and the oidc
issuer is the GitLab instance domain e.g. https://gitlab.com
Example verification of the podinfo module:
cosign verify ghcr.io/stefanprodan/modules/podinfo:latest \
--certificate-identity-regexp="^https://github.com/stefanprodan/podinfo.*$" \
--certificate-oidc-issuer=https://token.actions.githubusercontent.com
To verify the module signature while pulling:
timoni mod pull oci://ghcr.io/my-org/modules/my-app -v 1.0.0 \
--output ./my-module \
--verify=cosign \
--certificate-identity-regexp=<your email address> \
--certificate-oidc-issuer-regexp=<your issuer URL>