Skip to content

fix(gha): mint the Go-publish token from the open-constructs-cdktn App - #368

Merged
so0k merged 3 commits into
mainfrom
fix/go-publish-app-token
Aug 6, 2026
Merged

fix(gha): mint the Go-publish token from the open-constructs-cdktn App#368
so0k merged 3 commits into
mainfrom
fix/go-publish-app-token

Conversation

@so0k

@so0k so0k commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Problem

The release_golang job authenticates with TERRAFORM_CDK_GO_REPO_GITHUB_TOKEN — a user PAT that has expired. GitHub 401s the push, headless git falls back to an interactive password prompt, and the job dies:

fatal: could not read Password for 'https://***@github.com': No such device or address
    Command failed: git push origin cdktn/v0.24.0-pre.95

Both the original publish_next run and a fresh rerun (31085026499) failed identically, so this is credential death, not token-TTL flakiness. This currently blocks the 0.24.0 release cut (#303) — the stable flow publishes Go with the same secret.

Fix

Mint an installation token from the open-constructs-cdktn GitHub App (installation 138220829) whose credentials are already in this repo's secrets (GH_APP_ID / GH_APP_PRIVATE_KEY), scoped to cdk-terrain-go, and use it as GITHUB_TOKEN for publib-golang. Fresh every run, expires in an hour, no PAT to rot. Same pinned create-github-app-token@v2 SHA as release-please.yml / pnpm-upgrade.yml.

If the App installation turns out not to cover cdk-terrain-go, the mint step fails fast with a clear error — fallback is rotating the PAT.

Closes #66 (this was exactly the failure mode that issue predicted).

Verification

Merging this triggers the next pre-release flow on main, which will exercise the new token path end-to-end (expect v0.24.0-pre.96 to land in cdk-terrain-go). A green publish_next / Release Go to Github Repo (next) is the all-clear to merge #303.

🤖 Generated with Claude Code

The Go release job authenticated with TERRAFORM_CDK_GO_REPO_GITHUB_TOKEN,
a user PAT that expired: GitHub 401s the push, headless git falls back to
prompting, and the job dies with 'could not read Password for
https://***@github.com'. Both the original run and a fresh rerun failed
identically on v0.24.0-pre.95.

Mint an installation token from the open-constructs-cdktn GitHub App
(GH_APP_ID / GH_APP_PRIVATE_KEY repo secrets) instead, scoped to
cdk-terrain-go — the repo publib-golang pushes to. Same pinned
create-github-app-token@v2 the other workflows use.

Closes #66.
@so0k
so0k requested a review from a team as a code owner August 6, 2026 10:25
@so0k so0k changed the title fix(ci): mint the Go-publish token from the open-constructs-cdktn App fix(gha): mint the Go-publish token from the open-constructs-cdktn App Aug 6, 2026
@so0k so0k added ci/skip-examples Skip Examples Testing in PR ci/skip-integration Skips Integration Testing on PR ci/skip-provider-integration Skips Provider Integration Tests on PR ci/skip-unit Skips Unit Testing on PR labels Aug 6, 2026
zizmor's github-app audit: without a permission-* input the minted token
inherits every permission the installation has. publib-golang only
pushes commits and tags, so contents:write is the whole requirement.
@sakul-learning

Copy link
Copy Markdown
Contributor

The App-token implementation in .github/workflows/release-publish.yml:202-217 is pinned, scoped to open-constructs/cdk-terrain-go, and limited to contents: write, so the new Go-publish credential path looks good. One cleanup remains in the reusable-workflow interface: .github/workflows/release-publish.yml:33-34 still declares TERRAFORM_CDK_GO_REPO_GITHUB_TOKEN as required even though release_golang no longer uses it. This means the expired PAT must remain provisioned to satisfy the workflow contract; removing it after this migration can prevent the reusable workflow from being invoked. Please remove that obsolete required-secret declaration. Optionally, declare GH_APP_ID and GH_APP_PRIVATE_KEY as the credentials the workflow now consumes; they are currently available through the callers’ secrets: inherit.

Workflow security scan: 1 changed workflow (.github/workflows/release-publish.yml), 119 findings at the merge-base baseline, 6 findings in this workflow at the PR head, and 0 new or touched findings — ✅ PASS. The remaining findings are pre-existing backlog, not blockers for this PR.

…w contract

The reusable workflow still required the expired PAT, which would have
kept it provisioned forever just to satisfy the interface. Declare the
App credentials release_golang actually consumes instead; both callers
use 'secrets: inherit', so the interface swap is transparent.
@so0k

so0k commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

Done in f35a470: TERRAFORM_CDK_GO_REPO_GITHUB_TOKEN is out of the workflow_call contract, and GH_APP_ID/GH_APP_PRIVATE_KEY are declared as the credentials the workflow now consumes (both callers use secrets: inherit, so the swap is transparent). Once this merges, the expired PAT secret can be deleted from the repo settings entirely.

@so0k
so0k merged commit 179f10c into main Aug 6, 2026
14 checks passed
@so0k
so0k deleted the fix/go-publish-app-token branch August 6, 2026 11:29
@sakul-learning

Copy link
Copy Markdown
Contributor

Approved after re-review at f35a4704.

The reusable-workflow secret contract in .github/workflows/release-publish.yml now matches the Go publish implementation: the obsolete TERRAFORM_CDK_GO_REPO_GITHUB_TOKEN requirement is removed, GH_APP_ID and GH_APP_PRIVATE_KEY are declared as required, and both callers provide them through secrets: inherit. The App token remains SHA-pinned, restricted to open-constructs/cdk-terrain-go, and limited to contents: write.

The latest delta passes git diff --check, applicable CI checks are green, and the baseline-versus-head workflow security comparison found no new findings. No remaining blockers found.

so0k added a commit that referenced this pull request Aug 6, 2026
)

Follow-up to #368. The `GH_APP_ID`/`GH_APP_PRIVATE_KEY` secrets — unused
by any workflow for the 7 months before #368 adopted them — evidently do
not describe an app installed on `cdk-terrain-go`: the mint fails with a
404 on the installation lookup ([run
31097478176](https://github.com/open-constructs/cdk-terrain/actions/runs/31097478176))
even after the repo was added to open-constructs-cdktn's installation.

Switch `release_golang` to the **CDKTN Maintainers** app
(`CDKTN_MAINTAINERS_APP_ID`/`_PRIVATE_KEY` org secrets) — the app
`release-please.yml` and `pnpm-upgrade.yml` authenticate with
successfully in this repo every day.

⚠️ One org-admin precondition: the maintainers app's installation must
include **`cdk-terrain-go`** (with Contents: write). @hoegertn — the
installation screenshot you shared listing `cdk-terrain`,
`cdk-terrain-docs`, `cdk-terrain-go` — if that was this app's
installation and it's saved, we're already set.

Verification: merge triggers the `next` flow; a green `publish_next /
Release Go to Github Repo (next)` with `v0.24.0-pre.96` in
cdk-terrain-go is the all-clear to cut 0.24.0 (#303).

🤖 Generated with [Claude Code](https://claude.com/claude-code)
so0k added a commit that referenced this pull request Aug 6, 2026
)

Third and final piece of the Go-publish credential fix (#368#369 →
this). Run
[31111049134](https://github.com/open-constructs/cdk-terrain/actions/runs/31111049134)
proved the mint works (CDKTN Maintainers app, installation covers
`cdk-terrain-go`) — the job got all the way to `git push origin
cdktn/v0.24.0-pre.97` before dying with the same password prompt.

Cause: publib embeds `GITHUB_TOKEN` verbatim as URL userinfo. A bare
`ghs_` installation token becomes a **username-only** URL, which GitHub
rejects for App tokens — they authenticate over HTTPS only as
`x-access-token:<token>`. PATs tolerate the bare form, which is why this
never bit before the PAT died.

Fix is the one-line prefix — the exact wiring `@cdktn/provider-project`
generates for the provider fleet's `release_golang`, proven green on
cdktn-provider-snowflake's Go publish this morning:

```yaml
GITHUB_TOKEN: x-access-token:${{ steps.go-app-token.outputs.token }}
```

🤖 Generated with [Claude Code](https://claude.com/claude-code)
so0k pushed a commit that referenced this pull request Aug 7, 2026
🤖 Release PR — merge to cut a new release. Kept open and rebased
as commits land on `main`.
---


<details><summary>0.24.0</summary>

##
[0.24.0](v0.23.4...v0.24.0)
(2026-08-06)


### ⚠ BREAKING CHANGES

* **lib:** validate Terraform function versions by default
([#362](#362))
* **deps:** Require Node 22 minimum
([#345](#345))
* **lib:** preserve symlinks in TerraformAsset walkers
([#321](#321))
* **cli:** replace node-fetch with undici
([#306](#306))

### Features

* **lib:** canonical asset hashes behind the canonicalAssetHashes
feature flag
([#323](#323))
([76dd4ff](76dd4ff))
* **lib:** validate Terraform function versions by default
([#362](#362))
([4ac0736](4ac0736))
* support newer provider plugin-protocol features via targetVersions
(RFC-04)
([#296](#296))
([90322f9](90322f9))


### Bug Fixes

* **cli:** don't downgrade prebuilt providers on a transient registry
failure
([#298](#298))
([a960c5c](a960c5c))
* **cli:** include dev dependencies in npm version lookup
([#280](#280))
([955204a](955204a))
* **docs:** fix stale constructs pin breaking with()/IMixin docs
([#305](#305))
([605cf63](605cf63))
* **gha:** Allow pnpm to update the lockfile after package updates
([#318](#318))
([a899b7c](a899b7c))
* **gha:** Fix pnpm upgrade workflow
([#335](#335))
([e1a69fc](e1a69fc))
* **gha:** flip merged release PR label to autorelease: tagged
([#302](#302))
([8d64f6c](8d64f6c))
* **gha:** mint the Go-publish token from the CDKTN Maintainers app
([#369](#369))
([71921ce](71921ce))
* **gha:** mint the Go-publish token from the open-constructs-cdktn App
([#368](#368))
([179f10c](179f10c))
* **gha:** pass the Go-publish App token as x-access-token userinfo
([#370](#370))
([4e3ff19](4e3ff19))
* **lib:** Disallow constructs 10.8 until support can be added
([#363](#363))
([8bdae0d](8bdae0d))
* **lib:** preserve symlinks in TerraformAsset walkers
([#321](#321))
([6360e20](6360e20))
* typo in `moveFromId` JSDoc
([#355](#355))
([e1cf8ce](e1cf8ce))


### Miscellaneous Chores

* **cli:** replace Ink + React with smaller-tree CLI libraries
([#264](#264))
([a6aff7e](a6aff7e))
* **cli:** replace node-fetch with undici
([#306](#306))
([1317141](1317141))
* **deps:** bump glob to 13.0.6
([#307](#307))
([47ee2bb](47ee2bb))
* **deps:** bump the github-actions-backward-compatible group with 2
updates
([#295](#295))
([eab2a01](eab2a01))
* **deps:** replace lerna with nx
([#315](#315))
([94999fc](94999fc))
* **deps:** Require Node 22 minimum
([#345](#345))
([2bf315d](2bf315d))
* **deps:** update ci-info to 4.4.0 across all packages
([#329](#329))
([557a163](557a163))
* **deps:** update fs-extra to 11.3.6 across all packages
([#328](#328))
([95753a9](95753a9))
* **deps:** update minimatch to 10.2.5
([#330](#330))
([d1c1c53](d1c1c53))
* **deps:** Update sscaff to v2.0.388
([#331](#331))
([38ea0ba](38ea0ba))
* **deps:** Update zod to v4.4.3
([#332](#332))
([c10ee35](c10ee35))
* **deps:** Upgrade dependencies
([#347](#347))
([45d3a66](45d3a66))
* remove cdktf from tests
([#277](#277))
([dc9a8e9](dc9a8e9))
* ship Terraform 1.15.8 in the jsii-terraform image
([#367](#367))
([deaa9b0](deaa9b0))
* Upgrade dependencies for lib
([#348](#348))
([d616f17](d616f17))
</details>

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: open-constructs-cdktn[bot] <291052431+open-constructs-cdktn[bot]@users.noreply.github.com>
X-Guardian pushed a commit to X-Guardian/cdk-terrain that referenced this pull request Aug 10, 2026
open-constructs#368)

## Problem

The `release_golang` job authenticates with
`TERRAFORM_CDK_GO_REPO_GITHUB_TOKEN` — a user PAT that has expired.
GitHub 401s the push, headless git falls back to an interactive password
prompt, and the job dies:

```
fatal: could not read Password for 'https://***@github.com': No such device or address
    Command failed: git push origin cdktn/v0.24.0-pre.95
```

Both the original `publish_next` run and a fresh rerun
([31085026499](https://github.com/open-constructs/cdk-terrain/actions/runs/31085026499))
failed identically, so this is credential death, not token-TTL
flakiness. **This currently blocks the 0.24.0 release cut** (open-constructs#303) — the
stable flow publishes Go with the same secret.

## Fix

Mint an installation token from the **open-constructs-cdktn** GitHub App
([installation
138220829](https://github.com/apps/open-constructs-cdktn/installations/138220829))
whose credentials are already in this repo's secrets (`GH_APP_ID` /
`GH_APP_PRIVATE_KEY`), scoped to `cdk-terrain-go`, and use it as
`GITHUB_TOKEN` for `publib-golang`. Fresh every run, expires in an hour,
no PAT to rot. Same pinned `create-github-app-token@v2` SHA as
release-please.yml / pnpm-upgrade.yml.

If the App installation turns out not to cover `cdk-terrain-go`, the
mint step fails fast with a clear error — fallback is rotating the PAT.

Closes open-constructs#66 (this was exactly the failure mode that issue predicted).

## Verification

Merging this triggers the `next` pre-release flow on main, which will
exercise the new token path end-to-end (expect `v0.24.0-pre.96` to land
in cdk-terrain-go). A green `publish_next / Release Go to Github Repo
(next)` is the all-clear to merge open-constructs#303.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
X-Guardian pushed a commit to X-Guardian/cdk-terrain that referenced this pull request Aug 10, 2026
…pen-constructs#369)

Follow-up to open-constructs#368. The `GH_APP_ID`/`GH_APP_PRIVATE_KEY` secrets — unused
by any workflow for the 7 months before open-constructs#368 adopted them — evidently do
not describe an app installed on `cdk-terrain-go`: the mint fails with a
404 on the installation lookup ([run
31097478176](https://github.com/open-constructs/cdk-terrain/actions/runs/31097478176))
even after the repo was added to open-constructs-cdktn's installation.

Switch `release_golang` to the **CDKTN Maintainers** app
(`CDKTN_MAINTAINERS_APP_ID`/`_PRIVATE_KEY` org secrets) — the app
`release-please.yml` and `pnpm-upgrade.yml` authenticate with
successfully in this repo every day.

⚠️ One org-admin precondition: the maintainers app's installation must
include **`cdk-terrain-go`** (with Contents: write). @hoegertn — the
installation screenshot you shared listing `cdk-terrain`,
`cdk-terrain-docs`, `cdk-terrain-go` — if that was this app's
installation and it's saved, we're already set.

Verification: merge triggers the `next` flow; a green `publish_next /
Release Go to Github Repo (next)` with `v0.24.0-pre.96` in
cdk-terrain-go is the all-clear to cut 0.24.0 (open-constructs#303).

🤖 Generated with [Claude Code](https://claude.com/claude-code)
X-Guardian pushed a commit to X-Guardian/cdk-terrain that referenced this pull request Aug 10, 2026
…pen-constructs#370)

Third and final piece of the Go-publish credential fix (open-constructs#368open-constructs#369 →
this). Run
[31111049134](https://github.com/open-constructs/cdk-terrain/actions/runs/31111049134)
proved the mint works (CDKTN Maintainers app, installation covers
`cdk-terrain-go`) — the job got all the way to `git push origin
cdktn/v0.24.0-pre.97` before dying with the same password prompt.

Cause: publib embeds `GITHUB_TOKEN` verbatim as URL userinfo. A bare
`ghs_` installation token becomes a **username-only** URL, which GitHub
rejects for App tokens — they authenticate over HTTPS only as
`x-access-token:<token>`. PATs tolerate the bare form, which is why this
never bit before the PAT died.

Fix is the one-line prefix — the exact wiring `@cdktn/provider-project`
generates for the provider fleet's `release_golang`, proven green on
cdktn-provider-snowflake's Go publish this morning:

```yaml
GITHUB_TOKEN: x-access-token:${{ steps.go-app-token.outputs.token }}
```

🤖 Generated with [Claude Code](https://claude.com/claude-code)
X-Guardian pushed a commit to X-Guardian/cdk-terrain that referenced this pull request Aug 10, 2026
🤖 Release PR — merge to cut a new release. Kept open and rebased
as commits land on `main`.
---


<details><summary>0.24.0</summary>

##
[0.24.0](open-constructs/cdk-terrain@v0.23.4...v0.24.0)
(2026-08-06)


### ⚠ BREAKING CHANGES

* **lib:** validate Terraform function versions by default
([open-constructs#362](open-constructs#362))
* **deps:** Require Node 22 minimum
([open-constructs#345](open-constructs#345))
* **lib:** preserve symlinks in TerraformAsset walkers
([open-constructs#321](open-constructs#321))
* **cli:** replace node-fetch with undici
([open-constructs#306](open-constructs#306))

### Features

* **lib:** canonical asset hashes behind the canonicalAssetHashes
feature flag
([open-constructs#323](open-constructs#323))
([76dd4ff](open-constructs@76dd4ff))
* **lib:** validate Terraform function versions by default
([open-constructs#362](open-constructs#362))
([4ac0736](open-constructs@4ac0736))
* support newer provider plugin-protocol features via targetVersions
(RFC-04)
([open-constructs#296](open-constructs#296))
([90322f9](open-constructs@90322f9))


### Bug Fixes

* **cli:** don't downgrade prebuilt providers on a transient registry
failure
([open-constructs#298](open-constructs#298))
([a960c5c](open-constructs@a960c5c))
* **cli:** include dev dependencies in npm version lookup
([open-constructs#280](open-constructs#280))
([955204a](open-constructs@955204a))
* **docs:** fix stale constructs pin breaking with()/IMixin docs
([open-constructs#305](open-constructs#305))
([605cf63](open-constructs@605cf63))
* **gha:** Allow pnpm to update the lockfile after package updates
([open-constructs#318](open-constructs#318))
([a899b7c](open-constructs@a899b7c))
* **gha:** Fix pnpm upgrade workflow
([open-constructs#335](open-constructs#335))
([e1a69fc](open-constructs@e1a69fc))
* **gha:** flip merged release PR label to autorelease: tagged
([open-constructs#302](open-constructs#302))
([8d64f6c](open-constructs@8d64f6c))
* **gha:** mint the Go-publish token from the CDKTN Maintainers app
([open-constructs#369](open-constructs#369))
([71921ce](open-constructs@71921ce))
* **gha:** mint the Go-publish token from the open-constructs-cdktn App
([open-constructs#368](open-constructs#368))
([179f10c](open-constructs@179f10c))
* **gha:** pass the Go-publish App token as x-access-token userinfo
([open-constructs#370](open-constructs#370))
([4e3ff19](open-constructs@4e3ff19))
* **lib:** Disallow constructs 10.8 until support can be added
([open-constructs#363](open-constructs#363))
([8bdae0d](open-constructs@8bdae0d))
* **lib:** preserve symlinks in TerraformAsset walkers
([open-constructs#321](open-constructs#321))
([6360e20](open-constructs@6360e20))
* typo in `moveFromId` JSDoc
([open-constructs#355](open-constructs#355))
([e1cf8ce](open-constructs@e1cf8ce))


### Miscellaneous Chores

* **cli:** replace Ink + React with smaller-tree CLI libraries
([open-constructs#264](open-constructs#264))
([a6aff7e](open-constructs@a6aff7e))
* **cli:** replace node-fetch with undici
([open-constructs#306](open-constructs#306))
([1317141](open-constructs@1317141))
* **deps:** bump glob to 13.0.6
([open-constructs#307](open-constructs#307))
([47ee2bb](open-constructs@47ee2bb))
* **deps:** bump the github-actions-backward-compatible group with 2
updates
([open-constructs#295](open-constructs#295))
([eab2a01](open-constructs@eab2a01))
* **deps:** replace lerna with nx
([open-constructs#315](open-constructs#315))
([94999fc](open-constructs@94999fc))
* **deps:** Require Node 22 minimum
([open-constructs#345](open-constructs#345))
([2bf315d](open-constructs@2bf315d))
* **deps:** update ci-info to 4.4.0 across all packages
([open-constructs#329](open-constructs#329))
([557a163](open-constructs@557a163))
* **deps:** update fs-extra to 11.3.6 across all packages
([open-constructs#328](open-constructs#328))
([95753a9](open-constructs@95753a9))
* **deps:** update minimatch to 10.2.5
([open-constructs#330](open-constructs#330))
([d1c1c53](open-constructs@d1c1c53))
* **deps:** Update sscaff to v2.0.388
([open-constructs#331](open-constructs#331))
([38ea0ba](open-constructs@38ea0ba))
* **deps:** Update zod to v4.4.3
([open-constructs#332](open-constructs#332))
([c10ee35](open-constructs@c10ee35))
* **deps:** Upgrade dependencies
([open-constructs#347](open-constructs#347))
([45d3a66](open-constructs@45d3a66))
* remove cdktf from tests
([open-constructs#277](open-constructs#277))
([dc9a8e9](open-constructs@dc9a8e9))
* ship Terraform 1.15.8 in the jsii-terraform image
([open-constructs#367](open-constructs#367))
([deaa9b0](open-constructs@deaa9b0))
* Upgrade dependencies for lib
([open-constructs#348](open-constructs#348))
([d616f17](open-constructs@d616f17))
</details>

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: open-constructs-cdktn[bot] <291052431+open-constructs-cdktn[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/skip-examples Skip Examples Testing in PR ci/skip-integration Skips Integration Testing on PR ci/skip-provider-integration Skips Provider Integration Tests on PR ci/skip-unit Skips Unit Testing on PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Replace user PAT with GitHub App for Go publishing

2 participants