HYPERFLEET-1237 - feat: add JWT bearer token auth to HyperFleet API client#234
HYPERFLEET-1237 - feat: add JWT bearer token auth to HyperFleet API client#234rh-amarin wants to merge 3 commits into
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds JWT bearer-token auth for the HyperFleet API client, with file-backed token loading, TTL caching, and request header injection. Helm chart values/templates now mount a projected ServiceAccount token, set auth env vars, and validate Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant Helm as Helm chart
participant Adapter as adapter main
participant Client as HyperFleet API client
participant TokenFile as projected token file
participant API as HyperFleet API
Helm->>Adapter: auth values + env vars
Adapter->>Client: WithAuth(AuthConfig)
Client->>TokenFile: read token
TokenFile-->>Client: JWT bearer token
Client->>API: request with Authorization header
API-->>Client: response
🚥 Pre-merge checks | ✅ 10 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (10 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
✨ Simplify code
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
internal/hyperfleetapi/token_test.go (1)
84-111: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winDirect field manipulation
ts.expiresAt = time.Now().Add(-time.Second).UnixNano()(Line 98) will need updating totime.Now().Add(-time.Second)ifexpiresAtis switched totime.Timeper the token.go comment.🤖 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 `@internal/hyperfleetapi/token_test.go` around lines 84 - 111, The test is manually setting the cache expiration using a raw Unix nano value, but the token cache is being changed to store expiration as a time.Time. Update TestFileTokenSource_RefreshesAfterTTL to expire the cache by assigning a time.Time value to ts.expiresAt instead of using UnixNano, and keep the refresh assertion against FileTokenSource.get so the test matches the new expiresAt type.
🤖 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 `@charts/templates/deployment.yaml`:
- Around line 163-167: The Hyperfleet auth volumeMount in the deployment
template can resolve to a reserved parent directory, causing duplicate mountPath
conflicts in the pod spec. Update the chart logic around the
hyperfleet-api-token mount to validate
.Values.adapterConfig.hyperfleetApi.auth.tokenPath via a new _helpers.tpl guard,
and reject values whose dir(tokenPath) collapses to /etc/adapter or /etc/broker
before rendering the mount.
In `@internal/hyperfleetapi/token.go`:
- Around line 14-20: The token cache expiry logic in fileTokenSource uses
wall-clock UnixNano comparisons, which can keep serving stale tokens if the
system clock moves backward. Update fileTokenSource to store and compare
time.Time values instead of raw UnixNano, and use the existing time-based
comparisons so monotonic clock behavior is preserved when checking expiration in
the token fetch/cache path. Adjust the cached expiry handling around
fileTokenSource, expiresAt, and the read/refresh logic so the TTL is enforced
relative to time.Time rather than wall-clock integers.
---
Nitpick comments:
In `@internal/hyperfleetapi/token_test.go`:
- Around line 84-111: The test is manually setting the cache expiration using a
raw Unix nano value, but the token cache is being changed to store expiration as
a time.Time. Update TestFileTokenSource_RefreshesAfterTTL to expire the cache by
assigning a time.Time value to ts.expiresAt instead of using UnixNano, and keep
the refresh assertion against FileTokenSource.get so the test matches the new
expiresAt type.
🪄 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: Central YAML (base), Organization UI (inherited)
Review profile: CHILL
Plan: Enterprise
Run ID: b6fd24ce-e126-43dc-9502-3a76956cab7d
📒 Files selected for processing (16)
charts/templates/_helpers.tplcharts/templates/deployment.yamlcharts/values.yamlcmd/adapter/main.goconfigs/adapter-config-template.yamldocs/configuration.mddocs/deployment.mdinternal/configloader/types.gointernal/configloader/validator.gointernal/configloader/validator_test.gointernal/configloader/viper_loader.gointernal/hyperfleetapi/client.gointernal/hyperfleetapi/client_test.gointernal/hyperfleetapi/token.gointernal/hyperfleetapi/token_test.gointernal/hyperfleetapi/types.go
🔗 Linked repositories identified
CodeRabbit considers these linked repositories for cross-repo context during reviews:
openshift-hyperfleet/architecture(manual)openshift-hyperfleet/hyperfleet-api(manual)openshift-hyperfleet/hyperfleet-sentinel(manual)openshift-hyperfleet/hyperfleet-adapter(manual)openshift-hyperfleet/hyperfleet-broker(manual)
Risk Score: 4 —
|
| Signal | Detail | Points |
|---|---|---|
| PR size | 500 lines (>200) | +1 |
| Sensitive paths | cmd/ | +2 |
| Test coverage | Missing tests for: cmd/adapter | +1 |
Computed by hyperfleet-risk-scorer
…lient Add optional JWT bearer token authentication to the HyperFleet API HTTP client using Kubernetes projected ServiceAccount tokens. Auth is disabled by default so existing deployments are unaffected. - internal/hyperfleetapi: new fileTokenSource (TTL cache, double-checked locking), AuthConfig in ClientConfig, tokenSource on httpClient, WithAuth option, Authorization header injection in doRequest - internal/configloader: HyperfleetAPIAuthConfig alias, env var mappings for HYPERFLEET_API_AUTH_TOKEN_PATH / TOKEN_CACHE_TTL, auth validation in AdapterConfigValidator (absolute path, non-negative TTL) - cmd/adapter/main.go: wire WithAuth in createAPIClient - Helm chart: auth block in values.yaml (disabled by default), conditional projected ServiceAccountToken volume + env vars in deployment.yaml, tokenPath absolute-path validation in _helpers.tpl - docs: configuration reference, deployment guide, config template Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
38518b0 to
9a832db
Compare
Downgrade the hard validation error introduced in HYPERFLEET-1290 to a deprecation warning so existing adapter configs using api_call directly on preconditions continue to work without changes. The precondition executor already handles api_call at runtime — the breakage was purely in the semantic validator. Callers are now warned at startup to migrate to the params source.api_call style. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Summary
Changes
Go —
internal/hyperfleetapi/fileTokenSource(token.go): reads bearer token from disk with optional TTL-based in-memory cache and double-checked locking for safe concurrent useAuthConfigstruct added toClientConfig(token_path,token_cache_ttl)WithAuthclient option;tokenSourcefield onhttpClient;Authorization: Bearer <token>header injected indoRequestGo —
internal/configloader/HyperfleetAPIAuthConfigtype aliasHYPERFLEET_API_AUTH_TOKEN_PATH,HYPERFLEET_API_AUTH_TOKEN_CACHE_TTLvalidateHyperfleetAuthinAdapterConfigValidator: enforces non-empty absolute path and non-negative TTLGo —
cmd/adapter/main.gocreateAPIClientwiresWithAuthfrom configHelm chart
values.yaml:authblock underadapterConfig.hyperfleetApi(disabled by default, audience, tokenPath, expirationSeconds, tokenCacheTtl)deployment.yaml: conditional projectedserviceAccountTokenvolume + volume mount + env vars whenauth.enabled_helpers.tpl: Helm-time validation thattokenPathis an absolute pathDocs
docs/configuration.md: newauth.*fields and env vars documenteddocs/deployment.md: new HyperFleet API Authentication section with usage exampleconfigs/adapter-config-template.yaml: commented-outauthexampleTest plan
make test— unit tests pass (token_test.go, client_test.go auth tests, configloader validator auth tests)make build— binary builds cleanlymake lint— no lint errorsauth.enabled: false(default) — no behavior changeauth.enabled: true— confirmAuthorization: Bearerheader sent to HyperFleet API🤖 Generated with Claude Code