feat(agent): add SMS/Conjur JWT authentication alongside username/password - #817
Draft
roeezis wants to merge 2 commits into
Draft
feat(agent): add SMS/Conjur JWT authentication alongside username/password#817roeezis wants to merge 2 commits into
roeezis wants to merge 2 commits into
Conversation
…sword Adds a workload-identity auth path: the agent reads a projected ServiceAccount token, exchanges it at Secrets Manager SaaS (Conjur Cloud) authn-jwt for a short-lived Conjur access token, and presents it as a Bearer credential. The existing CyberArk Identity username/password login is retained; the method is selected automatically by config: config.cyberark.serviceId set -> Conjur JWT exchange (preferred) else ARK_USERNAME + ARK_SECRET -> username/password (unchanged) both set -> serviceId wins neither -> fail closed Only the token source changes, behind the existing identity.RequestAuthenticator seam; dataupload, service discovery and the upload pipeline are untouched. - internal/cyberark/conjur: authn-jwt exchange, ~8m token cache, Bearer - internal/cyberark/jwtsource: file source (projected SA token); spiffe deferred - internal/cyberark/identity: username/password login retained (split into username_password.go), behaviour unchanged - internal/cyberark/client.go: selectAuthenticator picks the method; NewRequestAuthenticator exposed for envelope/keyfetch - internal/envelope/keyfetch: JWKS fetch uses the same authenticator selector - pkg/agent/config.go: config.cyberark.* keys; service_id no longer mandatory - deploy/charts/disco-agent: projected token volume (aud=conjur), config keys, optional ARK_USERNAME/ARK_SECRET; docs Unit tests cover the four selection cases and the retained username/password login.
… base64 token Adds hack/onboard-disco-agent.sh: full onboarding for the DisCo agent's SMS/Conjur JWT auth, tenant-level (branch, uploader group, value-less authorization-probe secret) and per-cluster (authenticator, workload, grants). Runs entirely with the customer's own Conjur Cloud admin token; DisCo holds no Conjur identity of its own. Idempotent, fails closed, supports --dry-run/--skip-deploy. Also: account="conjur" is confirmed correct (was a POC placeholder), and the authn-jwt exchange now requests the base64-encoded access token explicitly (Conjur's canonical wire form), matching what the DisCo authorizer expects.
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.
Summary
Add a workload-identity JWT auth path to the DisCo agent, alongside the existing CyberArk Identity username/password login — not replacing it. Both methods coexist and the agent auto-selects by config. The agent reads a projected ServiceAccount token, exchanges it at Secrets Manager SaaS (Conjur Cloud)
authn-jwtfor a short-lived Conjur access token, and presents it as aBearercredential. Only the token source changes, behind the existingidentity.RequestAuthenticatorseam;dataupload/ service discovery / upload pipeline untouched.Auth-method selection (backward compatibility)
serviceId-wins lets a migrating install add the service-id before removing old creds — no rollout window with no method. Existing GA installs (UP creds, no serviceId) keep working with zero config change.
What changed
internal/cyberark/conjur/— authn-jwt exchange, short-lived token cache, setsBearer. ImplementsRequestAuthenticator. Requests the base64-encoded access token explicitly (Conjur's canonical wire form).internal/cyberark/jwtsource/—filesource (projected SA token, default/var/run/secrets/tokens/jwt);spiffedeferred.internal/cyberark/identity/username_password.go— legacy UP-login retained, behaviour unchanged.internal/cyberark/client.go—selectAuthenticatorpicks the method by config.account="conjur"confirmed correct (was a POC placeholder — verified against a live tenant).internal/envelope/keyfetch/— JWKS fetch uses the same authenticator selector.pkg/agent/config.go— MachineHub validation no longer hard-requiresservice_id; runtime fails closed if no method configured.helm — optional
ARK_USERNAME/ARK_SECRETenv alongside the projectedaud=conjurtoken volume; README + values document selection.config.cyberark.serviceIdmust be the bare authenticator service-id segment, not the full policy path.hack/onboard-disco-agent.sh(new) — full customer-run onboarding for the Conjur side of this feature, both tenant-level and per-cluster:Runs entirely with the customer's own Conjur admin token — the agent (and DisCo generally) holds no Conjur identity of its own. Idempotent (
409treated as success), fails closed, supports--dry-run/--skip-deploy.Authorization
The uploader-group membership check above is what the request-time authorizer relies on: the agent probes the value-less secret with its own token via a batch secret-value fetch; any
2xxresponse means the group grants it access (no secret value is ever needed or stored), anything else denies. This keeps the authorization decision entirely inside Secrets Manager — no new API surface needed there.Tests
internal/cyberark/...green incl. 4 auth-selection cases (serviceID→conjur, UP→identity, both→conjur wins, neither→error) and the retained UP-login tests.pkg/*/keyfetch verified statically (private venafi dep blocks full local build; CI exercises it).Status
Implemented and validated end-to-end against a live Secrets Manager tenant. Draft for review.
🤖 Generated with Claude Code