build: bump speakeasy-core to capture the registry license token - #2117
Merged
Conversation
/v1/auth/validate now returns license_jwt (speakeasy-registry#4702). Core tees it into the auth context (speakeasy-core#157); the CLI does not yet act on it. Follow-up wires it through to the generator via licensetoken.WithToken once openapi-generation#55 is released — that is the change that makes the generator, not the CLI, decide commercial output.
…k-go Pseudo-versions pending tags: speakeasy-core#157, speakeasy-client-sdk-go#50.
Replaces the pseudo-version pins now that speakeasy-core#157 is released. testify moves to 1.12.1 as the SDK's transitive minimum. Claude-Session: https://claude.ai/code/session_01DkiJPLbxuA3XKkK4bb7KcA
ThomasRooney
marked this pull request as ready for review
August 24, 2026 12:34
…k-go v3.27.0 pins go.mod/go.sum resolved on main's dependency set (openapi-generation v2.932.10, openapi v1.25.0, sdk-gen-config v1.58.0) with the two license-token pins re-applied; testify resolves to 1.12.1 as the SDK's transitive minimum. Claude-Session: https://claude.ai/code/session_01DkiJPLbxuA3XKkK4bb7KcA
AshGodfrey
approved these changes
Aug 24, 2026
ThomasRooney
pushed a commit
that referenced
this pull request
Aug 24, 2026
… auth (#2120) ## Why CLI **v1.795.2** breaks `speakeasy tag promote` for customers using registry tagging in CI (reported by Unkey): ``` Error: {"message":"err_unauthorized: unauthorized -- bearer token missing","status_code":403} Error: failed to tag registry images: error running speakeasy tag: ... speakeasy tag promote ``` **This is not a security exposure** — the server still enforces auth (`MustHaveConsistentWorkspaceIDClaimHTTP`). It's a spec/codegen defect: the client stopped *sending* credentials. `v1.795.1..v1.795.2` changes only `go.mod`/`go.sum`, and the operative line is `speakeasy-client-sdk-go/v3 v3.26.7 -> v3.27.0`. ## What broke v3.27.0 was the first regeneration of that SDK since 2025-05-06. It picked up a registry spec defect live since March: `openapi_artifacts.yaml` and `openapi_subscriptions.yaml` declare no top-level `security`, so once `speakeasy merge` began pushing global security down onto individual operations (#1952, registry#4559), their 13 operations composed as `security: []`. The generated SDK therefore dropped `utils.PopulateSecurity` from **all 11 Artifacts and both Subscriptions operations**. Verified against a local test server, identical calling code: | Operation | v3.26.7 | v3.27.0 | |---|---|---| | `Artifacts.PostTags` | `X-Api-Key` sent | **no auth header** | | `Artifacts.GetRevisions` | `X-Api-Key` sent | **no auth header** | | `Workspaces.Get` (control) | `X-Api-Key` sent | `X-Api-Key` sent | Affected CLI paths: `registry/tagging.go` -> `Artifacts.PostTags` (powers `tag promote`, `tag apply`, `ci tag`) and `internal/remote/sources.go:153` -> `Artifacts.GetRevisions`. This went unnoticed for five months because the other consumers (webapp, admin SDK) authenticate via `credentials: 'include'` cookies, so a missing security parameter is invisible to them. The header-authenticated public Go SDK was frozen by a broken regen since May 2025 — so it kept shipping correct pre-March code until now. ## Why revert rather than fix forward - Customers tracking `speakeasyVersion: latest` pick this up automatically; the breakage is spreading. - The real fix spans three repos (registry spec -> SDK regen -> CLI bump) and can't land quickly. - #2117 was explicit groundwork — "No behaviour change in this PR" — and what it enables (openapi-generation#55) is **still open**, so this gives up no live functionality. ## Verification - `go build ./...` — clean - `go test ./registry/... ./pkg/merge/...` — pass - Resolved deps back to `client-sdk-go v3.26.7` / `speakeasy-core v0.22.2`; all 11 `PopulateSecurity` calls restored ## Follow-up 1. Cut **v1.795.3** — the revert only helps once released. 2. Add top-level `security` to `openapi_artifacts.yaml` + `openapi_subscriptions.yaml` in speakeasy-registry. `openapi_admin.yaml` has the same defect (36 ops, no impact today). 3. Re-land #2117 on a fixed v3.27.1. 4. Consider a warning in `pkg/merge` when `setExplicitNoSecurity` marks operations unsecured — it silently performs a security-downgrading transform, which is what let this ship. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
ThomasRooney
added a commit
that referenced
this pull request
Aug 25, 2026
…and regression coverage Re-does #2117 (reverted in #2120): speakeasy-core v0.23.0 to capture the registry license token, and speakeasy-client-sdk-go v3.27.1 which restores auth on the artifacts/subscriptions operations that v3.27.0 silently dropped (generated from a composed spec that marked them 'security: []'; fixed at the source in speakeasy-registry#4707 and regenerated in speakeasy-client-sdk-go#51). Pinned to a v3.27.1 pseudo-version until the tag exists. Why nothing caught it last time: the SDK regression left every method signature unchanged — utils.PopulateSecurity simply vanished from those operations, so builds stayed green and the requests went out with no x-api-key. Registry e2e tests push/pull via oras/ocicommon credentials and never touch the generated SDK, and the only SDK callsites (registry/tagging.go PostTags, internal/remote/sources.go GetRevisions — which swallows errors) had no coverage. Two new guards: - internal/sdk/sdk_test.go: hermetic contract test asserting the x-api-key header is sent on Artifacts.PostTags and Artifacts.GetRevisions (verified to fail against v3.27.0). - integration/workflow_registry_test.go: TestRegistryFlow now finishes with 'speakeasy tag promote', exercising the platform-API auth path end-to-end (passes in 30s against prod).
ThomasRooney
added a commit
that referenced
this pull request
Aug 26, 2026
…+ regression coverage (#2121) ## Summary Re-does #2117 (reverted in #2120 after it broke registry auth for customers as v1.795.2): - `speakeasy-core` v0.22.2 → **v0.23.0** — captures the registry license token (the original point of #2117). - `speakeasy-client-sdk-go/v3` v3.26.7 → **v3.28.0** — v3.27.0 was generated from a composed spec that marked all 13 artifacts/subscriptions operations `security: []`, so `utils.PopulateSecurity` vanished from them and every `tag promote`/`tag apply`/`ci tag` went out without `x-api-key` → 403s. Fixed at the source (speakeasy-registry#4707: fragments now all declare the same top-level security, so merge keeps the global block; #4705 typed the `target_resource` enum) and regenerated from the registry-published spec (speakeasy-client-sdk-go#52, tagged v3.28.0). `PopulateSecurity` is back on all 11 Artifacts + 2 Subscriptions operations; the only operations without auth are the three that are public by design (`getAccessToken`, `handleCheckoutCallback`, `handleStripeWebhook`). No SDK signature changes vs v3.26.7. ## Why no test caught it last time The regression changed no method signatures — auth just silently disappeared from the requests, so builds and CI stayed green. Registry e2e tests (`TestRegistryFlow` etc.) push/pull via **oras/ocicommon** credentials and never touch the generated SDK; the only SDK-auth callsites are `registry/tagging.go` (`Artifacts.PostTags`) and `internal/remote/sources.go` (`Artifacts.GetRevisions`, which swallows errors entirely) — neither had coverage, and there wasn't a single `httptest` server in the repo to assert outbound headers. `release.yml` runs no tests at all. ## New regression guards 1. **`internal/sdk/sdk_test.go`** — hermetic contract test: `httptest` server + `InitSDKWithKey`, asserts the `x-api-key` header is present on `Artifacts.PostTags` and `Artifacts.GetRevisions` requests. **Verified to fail against v3.27.0** (header absent) and pass against v3.26.7 / v3.28.0. Catches any future SDK bump that drops auth, at unit-test speed with no credentials needed. 2. **`integration/workflow_registry_test.go`** — `TestRegistryFlow` now ends with `speakeasy tag promote -s test-source -t e2e-test`, exercising the platform-API (SDK) auth path end-to-end alongside the existing oras push/pull. Runs on every PR via `validate.yml` (`SPEAKEASY_API_KEY`). With v3.27.0 this step 403s. Possible follow-up (out of scope here): a `pkg/merge` warning when `setExplicitNoSecurity` stamps `security: []` onto operations, so composed-spec consumers notice before an SDK regen does. ## Verification (at v3.28.0) - `go build ./...`, `go test ./internal/sdk/` pass. - `go test ./integration/ -run 'TestRegistryFlow$'` passes (49s, real platform).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The registry now returns
license_jwton/v1/auth/validate— a registry-signed Ed25519 JWT proving commercial generation entitlement (speakeasy-api/speakeasy-registry#4702, live in prod). The open-source generator validates it offline (speakeasy-api/openapi-generation#55). Step 1 for the CLI is simply to stop dropping the token on the floor.What
speakeasy-coreto v0.23.0 (speakeasy-api/speakeasy-core#157, released) andspeakeasy-client-sdk-goto v3.27.0. Core teeslicense_jwtout of the validate response into the auth context (auth.GetLicenseTokenFromContext), because the pinned client SDK predates the field and its decoder drops unknown JSON.sdkgen.withGenerationContextfrom the access check, exactly as today.Follow-up (the meaningful change)
Once #55 tags: in
sdkgen.withGenerationContext, when generation is allowed and a token is present, attach it withlicensetoken.WithToken(ctx, tok)instead of pre-synthesising commercialAuthenticatedInfo— so the generator's validator establishes commercial output and the CLI stops being a path around the check. Also cache the token as the offline license file (30-day TTL). That PR also has to absorb the pre-existinginternal/schemasbreakage against generator ≥ v2.932.1 (unrelated to licensing, blocks any generator bump today).Sequencing
speakeasy-core#157 → this → openapi-generation#55 → CLI follow-up.
Testing
go build ./...;go test ./internal/sdkgen/ ./internal/run/green.Summary by cubic
Captures the registry
license_jwtfrom/v1/auth/validatein the auth context. Previously the CLI dropped this token; now it’s stored for later use. Behavior is unchanged and generation gating still follows the existing access check.speakeasy-corev0.23.0 (tees the token into context viaauth.GetLicenseTokenFromContext) andspeakeasy-client-sdk-go/v3v3.27.0 (adds typedLicenseJwt); mergedmainand re-resolved deps while keeping these pins.github.com/stretchr/testifyto v1.12.1; add indirectgo.yaml.in/yaml/v3v3.0.5 andgithub.com/spyzhov/ajsonv0.8.0; remove indirectgithub.com/davecgh/go-spew.licensetoken.WithTokenso the generator validates commercial output and cache it for offline use.Written for commit 81ecf8d. Summary will update on new commits.