Skip to content

Conversation

@shreyb
Copy link
Collaborator

@shreyb shreyb commented Dec 23, 2025

General idea

This PR implements functionality to allow operators to choose between using condor_vault_storer or direct htgettoken calls for obtaining tokens. This addresses Issue #124 by making the token retrieval method configurable rather than always requiring Condor involvement.

Key Changes:

  • Introduced a new GetToken WorkerType to support direct token retrieval without Condor
  • Merged StoreAndGetToken and StoreAndGetTokenInteractive WorkerTypes so that both StoreAndGetToken and GetToken support the use of an optional interactive configuration option.
  • Refactored WorkerType constants to remove the "WorkerType" suffix, and connected them to unexported Worker functions via the WorkerType.Worker() method
  • Updated token-push and refresh-uids-from-ferry to use these changes
  • Updated vendor dependencies including scitokens-go v0.3.3, lestrrat-go/jwx v1.2.30, and others

(This General Idea summary was adapted from copilot summary)

Added functionality by package

internal/vaultToken

  • htgettokenClient.go: Added a new type HtgettokenClient. Callers can use vaultToken.NewHtgettokenClient to get a new HtgettokenClient, and then use HtgettokenClient.GetToken to obtain a new bearer token and vault token. This is the interface to htgettoken
  • tokenStorer.go: Removed InteractiveTokenStorer and NonInteractiveTokenStorer types, and instead created a VaultStorerClient type that acts much like HtgettokenClient. The method VaultStorerClient.GetAndStoreToken obtains the vault token and stores it in a condor credd. This is the interface to condor_vault_storer.
  • commandExecutor.go: Both HtgettokenClient and VaultStorerClient use a new commandExecutor interface to implement interactive and non-interactive running of the htgettoken and condor_vault_storer commands.

internal/worker

  • workerType.go: Merge StoreAndGetTokenInteractive WorkerType into StoreAndGetToken. Added WorkerType.Worker method to map WorkerType values to unexported Worker functions. This gives callers a SINGLE way to call upon a worker. For example, if a user wants to start a GetToken worker, they would call the function returned by GetToken.Worker().
  • workerSpecificConfig.go: Added InteractiveTokenGetterOption and AlternateTokenGetterOption that callers may put into the Config type's workerSpecificConfig field.
  • workerSpecificConfig.go: Also added guardrail functions ValidRetryWorkerTypes and ValidTokenGetterWorkerTypes that allow callers to see which WorkerTypes actually support token-getting or retries respectively.
  • workerSpecificConfig.go: Added setters/getters for all possible values of enumeration type WorkerSpecificConfigOption. The setters mainly make sure the Config.workerSpecificConfig field is properly initialized, and allow you to store any value there. The getters type-check and validate the stored values.
  • getTokenWorker.go: Added a new worker func called getTokenWorker. This worker calls the various functions to obtain a vault token via htgettoken (by using the internal/vaultToken package), and handles communication of status and errors with the caller. It supports the use of the WorkerSpecificConfigOption InteractiveTokenGetterOption.
  • getTokenWorker.go: Added a new interface TokenGetter to allow for specification of alternate token-getters for mocking or future pluggability.
  • getTokenWorker.go: The type tokenGetterConfig implements TokenGetter, and runs htgettoken by creating a new vaultToken.HtgettokenClient, and calling its GetToken method, as described in the internal/vaultToken section above.
  • condorVaultStorerWorker.go: This is set up very similar to getTokenWorker.Go, with an unexported Worker func storeAndGetTokenWorker, which also supports the WorkerSpecificConfigOption InteractiveTokenGetterOption. The new tokenStorerAndGetter interface is declared here for testability and pluggability, but in the current case, that interface is implicitly implemented by internal/vaultToken.VaultStorerClient. I chose to structure it this way because there was a fair bit more information needed for the "helper" function and I didn't want to have too many arguments for the helper function storeAndGetTokensForSchedd.
  • kinitWorker.go, pingWorker.go, pushTokensWorker.go: Unexported Worker funcs, since they will be called via their corresponding WorkerType.
  • config.go, pushTokens.go: Since not all pushed tokens are stored in a credd, make sure we support the caller setting the Config.Schedds field to nil. This propagates to the pushTokensWorker worker and is now supported by that function.

Configuration changes (libsonnet/experimentConfig.libsonnet)

  • Allow for a new override called tokenGetterOverride that can be specified in an experiment configuration

token-push

  • config.go: New func getTokenGetterOverrideFromConfiguration that gets the tokenGetterOverride key from the experiment-specific configuration and validates it. A valid value for that key must be a string that corresponds to the name of a worker.WorkerType, but with the first letter lower-cased. So to override the default StoreAndGetToken WorkerType with a GetToken WorkerType, we use the key-value pair: tokenGetterOverride: "getToken". If the string passes this validation check, we then make sure that the specified worker type supports getting tokens using the exported worker.ValidTokenGetterWorkerTypes function. The return worker.WorkerType value if any checks fail is the default of worker.StoreAndGetToken.
  • workerType.go: Deprecate worker.StoreAndGetTokenInteractive as a valid WorkerType, and added a new helper function workerTypeFromConfig that takes a string and returns the corresponding WorkerType if the string is valid. This is used in the previous point for validation.
  • serviceConfigWorker.go: Because we unexported the various worker.Worker funcs, the func startServiceConfigWorkerForProcessing now accepts a worker.WorkerType wt, and calls wt.Worker() to launch the worker. I also added some error handling in case a worker needs to be skipped (like the worker.StoreAndGetTokens WorkerType if we're not using condor at all).
  • main.go: At the step where we would have launched the worker.StoreAndGetTokens worker func before, route each service's worker.Config object to either be run through worker.GetToken (htgettoken, indicated by step (2a) in the comments), or worker.StoreAndGetTokens (condor_vault_storer, or step (2b)). For the former case, set the Config's Schedds field to nil and skip querying the condor collector or cache for schedds.

refresh-uids-from-ferry

  • ferryAuthMethods.go: Func withKerberosJWTAuth should use the new vaultToken.HtgettokenClient to get a bearer and vault token.

Testing

After all of these changes, I ran the following tests to validate the change. All passed.

  • Unit tests
  • Mixed non-interactive mode
  • Just getting a token
  • Just default get and store token mode (old way)
  • Run-onboarding for both GetToken and StoreAndGetToken
  • Normal behavior with all the sample config files
    • managedTokens.allowNoErrors.json
    • managedTokens.badService.json
    • managedTokens.badSSHOpt.json
    • managedTokens.badSSHOptNoRetry.json
    • managedTokens.blockAllNotifications.json
    • managedTokens.blockOneNotification.json
    • managedTokens.blockSomeNotifications.json
    • managedTokens.collectorFallback.json
    • managedTokens.ERRORS.json
    • managedTokens.IPv4.json
    • managedTokens.json (No errors - standard-type config)
    • managedTokens.setupErrors.json
    • managedTokens.timeout.json

Closes #124.

…lers can throw out the bytes if they don't need it
…s not return an error. Also exported func so it is now GetCondorVaultTokenLocation
…ernal/vaultToken.GetCondorVaultTokenLocation instead
…hat returns the valid worker types for which retries are available
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR implements configurable token getter functionality to allow users to choose between using condor_vault_storer or direct htgettoken calls for obtaining tokens. This addresses Issue #124 by making the token retrieval method configurable rather than always requiring Condor involvement.

Key Changes:

  • Introduced a new GetToken WorkerType to support direct token retrieval without Condor
  • Added worker-specific configuration options for token getter behavior (interactive mode, alternate token getter)
  • Refactored WorkerType constants to use lowercase naming and added a Worker() method for cleaner dispatch
  • Updated vendor dependencies including scitokens-go v0.3.3, lestrrat-go/jwx v1.2.30, and others

Reviewed changes

Copilot reviewed 36 out of 132 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
internal/worker/workerType.go Refactored WorkerType enum, renamed constants (e.g., GetKerberosTicketsWorkerType → GetKerberosTickets), added GetToken type and Worker() method for function dispatch
internal/worker/workerSpecificConfig.go Added InteractiveTokenGetterOption and AlternateTokenGetterOption config options with supporting getters/setters
internal/worker/getTokenWorker.go New worker implementation for direct token retrieval with TokenGetter interface and tokenGetterConfig implementation
internal/worker/condorVaultStorerWorker.go Updated to support interactive token getter configuration option via getInteractiveTokenGetterOptionFromConfig
internal/worker/pushTokensWorker.go Updated to handle nil credds slice and use vaultToken.GetCondorVaultTokenLocation
internal/vaultToken/vaultToken.go Moved GetCondorVaultTokenLocation to be exported and improved error handling in user ID lookup
managedTokens.jsonnet, managedTokens.json Added vaultServer field to configuration
libsonnet/experimentConfig.libsonnet Added tokenGetterOverride to supported overrides list
go.mod Updated dependencies: scitokens-go v0.3.3, jwx v1.2.30, goccy/go-json v0.10.3, and others

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@shreyb shreyb marked this pull request as ready for review December 24, 2025 22:50
@shreyb shreyb requested a review from vitodb December 24, 2025 22:50
@shreyb
Copy link
Collaborator Author

shreyb commented Dec 24, 2025

@vitodb Feel free to ask me any questions you have about this. It's a pretty huge PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make StoreAndGetTokens configurable - don't always use condor

2 participants