Skip to content

Support opaque (non-JWT) tokens for sandbox environments#1116

Open
geowa4 wants to merge 1 commit into
openshift-online:mainfrom
geowa4:support-opaque-tokens
Open

Support opaque (non-JWT) tokens for sandbox environments#1116
geowa4 wants to merge 1 commit into
openshift-online:mainfrom
geowa4:support-opaque-tokens

Conversation

@geowa4

@geowa4 geowa4 commented Jun 9, 2026

Copy link
Copy Markdown

Summary

  • Add --opaque-token global flag and OCM_OPAQUE_TOKEN environment variable for environments that use opaque (non-JWT) tokens
  • Use unauthenticated SDK connection with a custom HTTP transport wrapper that injects the Bearer token directly, bypassing SDK token management
  • Skip token refresh in API commands (GET/POST/PATCH/DELETE) when opaque mode is active
  • Add opaque_token to ocm config get and ocm config set commands
  • Reject --opaque-token during ocm login with a guidance message showing the correct workflow
  • Add README documentation covering per-invocation and persistent usage modes
  • Supersedes Support opaque (non-JWT) tokens for sandbox environments #1115

Test plan

  • All existing tests pass (make test — 232 specs, 0 failures)
  • New unit tests for opaquetoken.Enabled() flag and env var handling
  • New unit tests for config.IsJWTToken() helper
  • New integration tests for opaque token preservation during GET requests
  • New integration tests for login rejection with --opaque-token
  • New integration tests for logout clearing opaque_token config
  • New integration tests for ocm token with opaque tokens (display, --generate rejection, JWT-only option rejection)
  • Manual testing with an actual opaque token against a sandbox environment

🤖 Generated with Claude Code

@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jun 9, 2026
@openshift-ci

openshift-ci Bot commented Jun 9, 2026

Copy link
Copy Markdown

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@openshift-ci

openshift-ci Bot commented Jun 9, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: geowa4
Once this PR has been reviewed and has the lgtm label, please assign rcampos2029 for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: bad31a44-01ab-4327-8ac9-ee9bdd0bb647

📥 Commits

Reviewing files that changed from the base of the PR and between 1e41da9 and 7bcad6b.

📒 Files selected for processing (23)
  • README.md
  • cmd/ocm/config/get/get.go
  • cmd/ocm/config/set/set.go
  • cmd/ocm/delete/cmd.go
  • cmd/ocm/get/cmd.go
  • cmd/ocm/login/cmd.go
  • cmd/ocm/main.go
  • cmd/ocm/patch/cmd.go
  • cmd/ocm/post/cmd.go
  • cmd/ocm/token/cmd.go
  • pkg/arguments/arguments.go
  • pkg/config/config.go
  • pkg/config/config_test.go
  • pkg/config/token.go
  • pkg/ocm/connection-builder/connection.go
  • pkg/opaquetoken/flag.go
  • pkg/opaquetoken/flag_test.go
  • pkg/opaquetoken/main_test.go
  • pkg/properties/properties.go
  • tests/get_test.go
  • tests/login_test.go
  • tests/logout_test.go
  • tests/token_test.go
✅ Files skipped from review due to trivial changes (1)
  • cmd/ocm/delete/cmd.go
🚧 Files skipped from review as they are similar to previous changes (18)
  • pkg/opaquetoken/flag_test.go
  • cmd/ocm/config/set/set.go
  • cmd/ocm/config/get/get.go
  • pkg/opaquetoken/main_test.go
  • cmd/ocm/main.go
  • tests/login_test.go
  • pkg/config/token.go
  • tests/token_test.go
  • tests/logout_test.go
  • pkg/properties/properties.go
  • cmd/ocm/get/cmd.go
  • cmd/ocm/patch/cmd.go
  • tests/get_test.go
  • pkg/arguments/arguments.go
  • cmd/ocm/login/cmd.go
  • pkg/ocm/connection-builder/connection.go
  • cmd/ocm/post/cmd.go
  • cmd/ocm/token/cmd.go

Summary by CodeRabbit

  • New Features

    • Added opaque-token mode via --opaque-token flag or OCM_OPAQUE_TOKEN env var; can be persisted with ocm config set opaque_token true.
    • Token output prints opaque tokens unchanged; JWT-specific options (--header/--payload/--signature) and generation are blocked for opaque tokens.
    • Commands that persist tokens now honor opaque-token mode and won’t overwrite stored opaque tokens.
  • Behavior Changes

    • ocm login rejects opaque-token mode; configure opaque tokens after login.
  • Documentation

    • README updated with opaque-token usage and examples.

Walkthrough

Adds opaque-token mode: config flag and detection, CLI flag/env wiring, connection transport injecting Authorization header, conditional token persistence in commands, JWT-inspection gating in token output, tests, and README documentation.

Changes

Opaque Token Feature

Layer / File(s) Summary
Config and JWT detection
pkg/properties/properties.go, pkg/config/token.go, pkg/config/config.go, pkg/config/config_test.go
Adds OpaqueToken field, changes Armed to accept opaqueMode, short-circuits access-token checks in opaque mode, adds IsJWTToken() and tests for armed logic and JWT detection.
Opaque token flag module
pkg/opaquetoken/flag.go, pkg/opaquetoken/flag_test.go, pkg/opaquetoken/main_test.go
New opaquetoken package with AddFlag() and Enabled() (reads flag or OCM_OPAQUE_TOKEN env); includes tests and Ginkgo entry.
Arguments and main CLI wiring
pkg/arguments/arguments.go, cmd/ocm/main.go
Adds AddOpaqueTokenFlag and wires --opaque-token into CLI persistent flags.
Connection builder and transport
pkg/ocm/connection-builder/connection.go
ConnectionBuilder derives opaqueMode, validates Armed(opaqueMode), skips SDK token wiring in opaque mode, and injects Authorization: Bearer <access-token> via opaqueTokenTransport.
Config get/set
cmd/ocm/config/get/get.go, cmd/ocm/config/set/set.go
Adds opaque_token to config get (prints boolean) and config set (parses boolean, reports parse errors).
Token command and JWT output handling
cmd/ocm/token/cmd.go
Loads config early and branches on opaque mode (blocks --generate in opaque mode, uses cfg tokens directly); JWT-inspection flags (--header/--payload/--signature) only work for JWTs and error for opaque tokens.
Login command
cmd/ocm/login/cmd.go
ocm login fails fast when opaque-token mode is enabled and instructs users to configure opaque tokens; tokens are assigned to config before save; minor comment fixes.
GET/POST/PATCH/DELETE commands
cmd/ocm/get/cmd.go, cmd/ocm/post/cmd.go, cmd/ocm/patch/cmd.go, cmd/ocm/delete/cmd.go
Load config earlier, return explicit "not logged in" when no config, and skip fetching/saving access/refresh tokens when opaque mode is active (cfg.OpaqueToken or opaquetoken.Enabled()).
Tests and README
tests/*, README.md
Adds tests for opaque-token flows (get preserves token, login rejects flag/env, token command prints opaque tokens and rejects JWT-only flags, logout removes opaque flag). README documents per-invocation and persistent opaque token workflows with examples.

Estimated code review effort:

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 27.78% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: adding support for opaque (non-JWT) tokens for sandbox environments.
Description check ✅ Passed The description is directly related to the changeset, providing a detailed summary of the feature, implementation approach, configuration options, and test coverage.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@geowa4 geowa4 force-pushed the support-opaque-tokens branch from 4e38a63 to f1a31ae Compare June 9, 2026 14:34
@geowa4

geowa4 commented Jun 9, 2026

Copy link
Copy Markdown
Author

Manual testing:

❯ bunx @earendil-works/gondolin bash --host-secret OCM_TOKEN@api.openshift.com=$(ocm token) --env OCM_URL='https://api.openshift.com' --env OCM_TOKEN_URL='https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token' --image gondolin-ocm:latest --mount-hostfs /Users/geowa4/Dev/repos/ocm-cli:/ocm-cli
(none):/# ocm config set access_token $OCM_TOKEN
(none):/# ocm config set token_url $OCM_TOKEN_URL
(none):/# ocm config set url $OCM_URL
(none):/# cat /tmp/.config/ocm/ocm.json
{
  "access_token": "GONDOLIN_SECRET_54da441784b1fe3eef888aad85071e70f8ca4b1ea4617343",
  "token_url": "https://sso.redhat.com/auth/realms/redhat-external/protocol/openid-connect/token",
  "url": "https://api.openshift.com"
}(none):/# OCM_OPAQUE_TOKEN=true ./ocm-cli/ocm-linux-arm64 whoami
{
  ...omitted...
  "username":"geowa4.openshift"
}
(none):/# ./ocm-cli/ocm-linux-arm64 whoami
Error: Failed to create OCM connection: token contains an invalid number of segments
(none):/# ./ocm-cli/ocm-linux-arm64 --opaque-token whoami
{
  ...omitted...
  "username":"geowa4.openshift"
}
(none):/# ./ocm-cli/ocm-linux-arm64 config set opaque_token true
(none):/# ./ocm-cli/ocm-linux-arm64 whoami
{
  ...omitted...
  "username":"geowa4.openshift"
}

@geowa4 geowa4 marked this pull request as ready for review June 9, 2026 17:14
@openshift-ci openshift-ci Bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jun 9, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (2)
pkg/opaquetoken/flag.go (1)

34-35: ⚡ Quick win

Use the shared env-key constant in the flag help text.

The help text duplicates OCM_OPAQUE_TOKEN as a raw string instead of reusing properties.OpaqueTokenEnvKey, which risks drift if the key changes.

Proposed diff
 import (
+	"fmt"
 	"os"
 	"strconv"

 	"github.com/spf13/pflag"

 	"github.com/openshift-online/ocm-cli/pkg/properties"
 )
@@
 	flags.BoolVar(
 		&enabled,
 		"opaque-token",
 		false,
 		"Treat the access token as an opaque (non-JWT) token. Can also be "+
-			"enabled by setting the OCM_OPAQUE_TOKEN environment variable.",
+			fmt.Sprintf("enabled by setting the %s environment variable.", properties.OpaqueTokenEnvKey),
 	)
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/opaquetoken/flag.go` around lines 34 - 35, The flag help text currently
embeds the literal "OCM_OPAQUE_TOKEN"; update it to reference the shared
constant properties.OpaqueTokenEnvKey instead so the help message stays in sync
with the env-key definition—locate the flag help string in
pkg/opaquetoken/flag.go (the variable that defines the flag help) and replace
the raw env var text with the properties.OpaqueTokenEnvKey symbol in the
concatenated help string.
pkg/config/config_test.go (1)

178-201: ⚡ Quick win

Add a refresh-token-only opaque-mode test case.

The new opaque coverage only exercises access-token paths. Please add a case asserting that opaque mode is not armed when only RefreshToken is present, so this regression path stays protected.

Suggested test addition
+ It("Is not armed in opaque mode when only refresh token is set", func() {
+   config := &Config{
+     RefreshToken: "opaque_refresh_only",
+     OpaqueToken:  true,
+     URL:          "http://my-server.example.com",
+     TokenURL:     "http://my-sso.example.com",
+   }
+   armed, reason, err := config.Armed(true)
+   Expect(err).ToNot(HaveOccurred())
+   Expect(armed).To(BeFalse())
+   Expect(reason).To(Equal("credentials aren't set"))
+ })
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/config/config_test.go` around lines 178 - 201, Add a new unit test that
constructs a Config with OpaqueToken set (e.g., OpaqueToken: true), no
AccessToken, and only RefreshToken populated (RefreshToken:
"some-refresh-token"), then call config.Armed(true) and assert that armed is
false (and check error/no-error per existing behavior); place the test alongside
the existing cases and reference the Config type and Armed method to ensure
opaque mode is not considered armed when only RefreshToken is present.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cmd/ocm/token/cmd.go`:
- Around line 113-120: The branch that handles opaque tokens (haveOpaqueToken
computed from opaquetoken.Enabled() || (cfg != nil && cfg.OpaqueToken)) can
dereference cfg when opaquetoken.Enabled() is true but cfg == nil; update the
opaque-token branch in cmd.go so that after detecting haveOpaqueToken you
explicitly check if cfg == nil and return a clear error (or handle missing
tokens) before accessing cfg.AccessToken and cfg.RefreshToken; ensure the
existing args.generate check remains and reference the symbols haveOpaqueToken,
opaquetoken.Enabled(), cfg, accessToken, refreshToken and args.generate when
making the change.

In `@pkg/config/config.go`:
- Around line 214-215: The current check sets refreshUsable when either
opaqueMode is true or IsEncryptedToken(c.RefreshToken) is true, which
erroneously treats a refresh token as usable in opaque mode; change the
condition in the logic that sets refreshUsable so that opaqueMode does NOT
enable it (e.g., only set refreshUsable when !opaqueMode &&
IsEncryptedToken(c.RefreshToken)), and verify any later use (the
armed-state/reporting logic that reads refreshUsable) relies on this corrected
flag so a service in opaqueMode won't be reported as "armed" based solely on
c.RefreshToken.

In `@README.md`:
- Around line 170-190: Replace the unlabeled code fences and prompt-style lines
in the README examples so markdownlint is satisfied: change the three
triple-backtick blocks containing the commands "ocm --opaque-token get
/api/clusters_mgmt/v1/clusters", the block with "export OCM_OPAQUE_TOKEN=true" /
"ocm get /api/clusters_mgmt/v1/clusters", and the block with "ocm login
--token=..." / "ocm config set access_token ..." / "ocm config set opaque_token
true" to use fenced code blocks labeled with bash (```bash) and remove leading
"$ " prompts from each command line so the examples are clean shell snippets.

---

Nitpick comments:
In `@pkg/config/config_test.go`:
- Around line 178-201: Add a new unit test that constructs a Config with
OpaqueToken set (e.g., OpaqueToken: true), no AccessToken, and only RefreshToken
populated (RefreshToken: "some-refresh-token"), then call config.Armed(true) and
assert that armed is false (and check error/no-error per existing behavior);
place the test alongside the existing cases and reference the Config type and
Armed method to ensure opaque mode is not considered armed when only
RefreshToken is present.

In `@pkg/opaquetoken/flag.go`:
- Around line 34-35: The flag help text currently embeds the literal
"OCM_OPAQUE_TOKEN"; update it to reference the shared constant
properties.OpaqueTokenEnvKey instead so the help message stays in sync with the
env-key definition—locate the flag help string in pkg/opaquetoken/flag.go (the
variable that defines the flag help) and replace the raw env var text with the
properties.OpaqueTokenEnvKey symbol in the concatenated help string.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: 9ef73458-6be2-4494-bbc5-d0c5c1d788a6

📥 Commits

Reviewing files that changed from the base of the PR and between f278043 and f1a31ae.

📒 Files selected for processing (23)
  • README.md
  • cmd/ocm/config/get/get.go
  • cmd/ocm/config/set/set.go
  • cmd/ocm/delete/cmd.go
  • cmd/ocm/get/cmd.go
  • cmd/ocm/login/cmd.go
  • cmd/ocm/main.go
  • cmd/ocm/patch/cmd.go
  • cmd/ocm/post/cmd.go
  • cmd/ocm/token/cmd.go
  • pkg/arguments/arguments.go
  • pkg/config/config.go
  • pkg/config/config_test.go
  • pkg/config/token.go
  • pkg/ocm/connection-builder/connection.go
  • pkg/opaquetoken/flag.go
  • pkg/opaquetoken/flag_test.go
  • pkg/opaquetoken/main_test.go
  • pkg/properties/properties.go
  • tests/get_test.go
  • tests/login_test.go
  • tests/logout_test.go
  • tests/token_test.go

Comment thread cmd/ocm/token/cmd.go
Comment thread pkg/config/config.go Outdated
Comment thread README.md Outdated
@geowa4 geowa4 force-pushed the support-opaque-tokens branch from f1a31ae to 2a831d0 Compare June 9, 2026 18:51

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
README.md (1)

170-191: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

The markdownlint violations flagged in the past review are still present.

The code fence language specifiers and shell prompt style issues identified in the previous review remain unaddressed. The past review comment provides a ready-to-apply fix.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` around lines 170 - 191, Add language specifiers to the fenced code
blocks and remove shell prompt characters so markdownlint errors are resolved:
change the three backtick fences to use "bash" (e.g., ```bash) for both command
blocks and remove the leading "$ " prompt from each command line inside those
fences (leave commands themselves intact), ensuring the examples under the ocm
get and the export/config examples are plain bash commands without prompt
characters.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@README.md`:
- Around line 170-191: Add language specifiers to the fenced code blocks and
remove shell prompt characters so markdownlint errors are resolved: change the
three backtick fences to use "bash" (e.g., ```bash) for both command blocks and
remove the leading "$ " prompt from each command line inside those fences (leave
commands themselves intact), ensuring the examples under the ocm get and the
export/config examples are plain bash commands without prompt characters.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: 26a44f7c-24b8-48db-a859-d696ba8bc6b4

📥 Commits

Reviewing files that changed from the base of the PR and between f1a31ae and 2a831d0.

📒 Files selected for processing (23)
  • README.md
  • cmd/ocm/config/get/get.go
  • cmd/ocm/config/set/set.go
  • cmd/ocm/delete/cmd.go
  • cmd/ocm/get/cmd.go
  • cmd/ocm/login/cmd.go
  • cmd/ocm/main.go
  • cmd/ocm/patch/cmd.go
  • cmd/ocm/post/cmd.go
  • cmd/ocm/token/cmd.go
  • pkg/arguments/arguments.go
  • pkg/config/config.go
  • pkg/config/config_test.go
  • pkg/config/token.go
  • pkg/ocm/connection-builder/connection.go
  • pkg/opaquetoken/flag.go
  • pkg/opaquetoken/flag_test.go
  • pkg/opaquetoken/main_test.go
  • pkg/properties/properties.go
  • tests/get_test.go
  • tests/login_test.go
  • tests/logout_test.go
  • tests/token_test.go
✅ Files skipped from review due to trivial changes (1)
  • pkg/opaquetoken/main_test.go
🚧 Files skipped from review as they are similar to previous changes (18)
  • tests/logout_test.go
  • tests/get_test.go
  • cmd/ocm/delete/cmd.go
  • cmd/ocm/main.go
  • tests/login_test.go
  • pkg/config/token.go
  • pkg/arguments/arguments.go
  • pkg/opaquetoken/flag.go
  • cmd/ocm/config/set/set.go
  • pkg/properties/properties.go
  • cmd/ocm/get/cmd.go
  • pkg/config/config.go
  • cmd/ocm/post/cmd.go
  • cmd/ocm/patch/cmd.go
  • pkg/ocm/connection-builder/connection.go
  • cmd/ocm/config/get/get.go
  • cmd/ocm/token/cmd.go
  • pkg/config/config_test.go

@geowa4 geowa4 force-pushed the support-opaque-tokens branch from 2a831d0 to 1e41da9 Compare June 9, 2026 19:04

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pkg/config/config.go (1)

214-221: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Skip refresh token validation in opaque mode to prevent spurious errors.

When opaqueMode is true, the condition !opaqueMode && IsEncryptedToken(...) is always false, so tokenUsable() is called on the refresh token. If a stale or malformed refresh token exists in config, this will return an error and cause Armed() to fail—even though the opaque access token is valid.

This is related to a past review concern about refresh token handling in opaque mode. The safest behavior is to skip refresh token validation entirely in opaque mode, since the feature relies solely on the access token.

Proposed fix
 haveRefresh := c.RefreshToken != ""
 refreshUsable := false
 if haveRefresh {
-	if !opaqueMode && IsEncryptedToken(c.RefreshToken) {
+	if opaqueMode {
+		// In opaque mode, skip refresh token validation entirely.
+		// Authentication relies on the opaque access token.
+		refreshUsable = false
+	} else if IsEncryptedToken(c.RefreshToken) {
 		refreshUsable = true
 	} else {
 		refreshUsable, err = tokenUsable(c.RefreshToken, 10*time.Second)
 		if err != nil {
 			return
 		}
 	}
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/config/config.go` around lines 214 - 221, The refresh-token validation
currently runs even in opaqueMode (causing Armed() to fail on stale/malformed
refresh tokens); change the conditional around
opaqueMode/IsEncryptedToken/tokenUsable so that when opaqueMode is true you do
not call tokenUsable() at all (e.g., short-circuit: if opaqueMode { set
refreshUsable = false } else if IsEncryptedToken(c.RefreshToken) { refreshUsable
= true } else { refreshUsable, err = tokenUsable(c.RefreshToken, 10*time.Second)
... }). Ensure you remove any early return on error in the opaque branch so
tokenUsable is never invoked when opaqueMode is true.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@pkg/config/config.go`:
- Around line 214-221: The refresh-token validation currently runs even in
opaqueMode (causing Armed() to fail on stale/malformed refresh tokens); change
the conditional around opaqueMode/IsEncryptedToken/tokenUsable so that when
opaqueMode is true you do not call tokenUsable() at all (e.g., short-circuit: if
opaqueMode { set refreshUsable = false } else if
IsEncryptedToken(c.RefreshToken) { refreshUsable = true } else { refreshUsable,
err = tokenUsable(c.RefreshToken, 10*time.Second) ... }). Ensure you remove any
early return on error in the opaque branch so tokenUsable is never invoked when
opaqueMode is true.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: 37327473-e968-40bc-bae8-14b20912d20c

📥 Commits

Reviewing files that changed from the base of the PR and between 2a831d0 and 1e41da9.

📒 Files selected for processing (23)
  • README.md
  • cmd/ocm/config/get/get.go
  • cmd/ocm/config/set/set.go
  • cmd/ocm/delete/cmd.go
  • cmd/ocm/get/cmd.go
  • cmd/ocm/login/cmd.go
  • cmd/ocm/main.go
  • cmd/ocm/patch/cmd.go
  • cmd/ocm/post/cmd.go
  • cmd/ocm/token/cmd.go
  • pkg/arguments/arguments.go
  • pkg/config/config.go
  • pkg/config/config_test.go
  • pkg/config/token.go
  • pkg/ocm/connection-builder/connection.go
  • pkg/opaquetoken/flag.go
  • pkg/opaquetoken/flag_test.go
  • pkg/opaquetoken/main_test.go
  • pkg/properties/properties.go
  • tests/get_test.go
  • tests/login_test.go
  • tests/logout_test.go
  • tests/token_test.go
✅ Files skipped from review due to trivial changes (2)
  • pkg/properties/properties.go
  • pkg/config/token.go
🚧 Files skipped from review as they are similar to previous changes (17)
  • cmd/ocm/main.go
  • cmd/ocm/config/get/get.go
  • tests/login_test.go
  • cmd/ocm/config/set/set.go
  • cmd/ocm/patch/cmd.go
  • tests/get_test.go
  • cmd/ocm/delete/cmd.go
  • cmd/ocm/post/cmd.go
  • pkg/opaquetoken/flag_test.go
  • pkg/opaquetoken/flag.go
  • tests/token_test.go
  • pkg/arguments/arguments.go
  • cmd/ocm/get/cmd.go
  • cmd/ocm/login/cmd.go
  • cmd/ocm/token/cmd.go
  • pkg/ocm/connection-builder/connection.go
  • pkg/config/config_test.go

Add --opaque-token flag and OCM_OPAQUE_TOKEN env var for environments
that use opaque tokens instead of JWTs. When enabled, the CLI sends
the access token as-is via a custom HTTP transport, bypassing SDK
token management and JWT parsing.

- Add opaquetoken package for flag/env var handling
- Use unauthenticated SDK connection with custom transport wrapper
- Skip token refresh in API commands (GET/POST/PATCH/DELETE)
- Add opaque_token to config get/set commands
- Reject --opaque-token during login with guidance message
- Add README documentation for per-invocation and persistent modes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@geowa4 geowa4 force-pushed the support-opaque-tokens branch from 1e41da9 to 7bcad6b Compare June 9, 2026 19:36
@rcampos2029 rcampos2029 added the priority/important-soon Must be staffed and worked on either currently, or very soon, ideally in time for the next release. label Jun 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

priority/important-soon Must be staffed and worked on either currently, or very soon, ideally in time for the next release.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants