Skip to content

ci: publish the module package as a signed OCI artifact - #15

Draft
UlysseCarpentier wants to merge 1 commit into
mainfrom
ci/oci-module-release
Draft

UlysseCarpentier wants to merge 1 commit into
mainfrom
ci/oci-module-release

Conversation

@UlysseCarpentier

Copy link
Copy Markdown
Contributor

Closes the distribution half of the OpenTofu module conformance checklist
(section 5): the module is published as a cosign-signed OCI artifact, and
consumers are given the digest to pin.

Decisions

  • One artifact for the whole repository, not one per cloud. A consumer
    addresses a module by subdirectory:
    oci://ghcr.io/do-now-io/socle//opentofu/gcp?digest=sha256:...
    The tradeoff: every cloud shares one version line, so a GCP release bumps
    AWS too. Worth revisiting once a second cloud module actually ships.
  • Public package on ghcr.io, so tofu init needs no credentials.
  • Signed by digest, never by tag — a tag is a mutable pointer.
  • Keyless cosign: Fulcio issues a short-lived certificate bound to this
    workflow's identity, so no private key exists to store or rotate.

The part that is not automatable

OpenTofu does not verify OCI signatures. It will pull a tampered artifact
without complaint. Signing only counts because the consumer runs
cosign verify before init, which is why the run summary prints that
command and the digest-pinned source line ready to copy.

Before the first tag

  • The ghcr package is created private. Making it public is a one-time manual
    step in the package settings; a workflow cannot do it.
  • Nothing yet forces a consumer to verify. That needs registry policy or an
    admission controller — deliberately out of scope here.

Verified

  • yamllint clean against the repository config.
  • actionlint exit 0.
  • oras push --artifact-type ... --format go-template flags confirmed
    against the tool's own help output, not from memory.
  • Not exercised end to end: no tag has been pushed, so the artifact has never
    actually been built. The first v* tag is the real test.

🤖 Generated with Claude Code

One artifact carries the whole repository, so a consumer addresses a cloud
by subdirectory: oci://ghcr.io/do-now-io/socle//opentofu/gcp?digest=...

The archive comes from git archive on the tag, so it holds exactly what the
tag holds — no .terraform directory, no lock file, no local edit. The push
sets artifactType application/vnd.opentofu.modulepkg with a single
archive/zip layer, which is the only shape OpenTofu accepts.

cosign signs the digest, never the tag: a tag is a mutable pointer. Keyless,
so no private key exists to store or rotate.

OpenTofu does not verify OCI signatures and will pull a tampered artifact
without complaint, so the run summary prints the cosign verify command and
the digest-pinned source line for consumers to copy.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@@ -0,0 +1,90 @@
---

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Je ne suis pas sûr qu'on le veuille ça ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C'est à dire? Le workflow entier ou juste les "---", si c'est le second c'est dans tous les autres fichiers aussi, ca se fait dans les workflows gha

Si c'est le workflow entier, peut-être que c'est trop tôt pour s'occuper de la release effectivment, je peux passer en draft pour plus tard

# signed with a keyless cosign signature.
#
# One artifact carries every cloud, so a consumer addresses a module by
# subdirectory: oci://ghcr.io/do-now-io/socle//opentofu/gcp?digest=sha256:...

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pourquoi pas utiliser le cdn de github ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Parce qu'une asset de release est adressée par une URL mutable, sans vérification de checksum côté OpenTofu : le consommateur ne peut pas garantir que ce que tofu init télécharge est bien ce que cosign a vérifié, alors qu'en OCI l'adresse est le digest.

@UlysseCarpentier
UlysseCarpentier marked this pull request as draft September 14, 2026 07:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants