feat(secretstores): Add Akeyless Secretstore - #4385
Conversation
Signed-off-by: Kobbi Gal <195813801+kgal-akl@users.noreply.github.com>
Signed-off-by: Kobbi Gal <195813801+kgal-akl@users.noreply.github.com>
|
This pull request has been automatically marked as stale because it has not had activity in the last 30 days. It will be closed in 7 days if no further activity occurs. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions! |
Signed-off-by: kgal-akl <kobbi.g@akeyless.io>
|
/ok-to-test |
sicoyle
left a comment
There was a problem hiding this comment.
first round of feedback from me - thank you!!!
| type: secretstores | ||
| name: akeyless | ||
| version: v1 | ||
| status: beta |
There was a problem hiding this comment.
typically when we introduce new components we make them alpha
| status: beta | |
| status: alpha |
| urls: | ||
| - title: Reference | ||
| url: https://docs.dapr.io/reference/components-reference/supported-secret-stores/akeyless/ | ||
| metadata: |
There was a problem hiding this comment.
pls mv the auth related fields into an authenticationProfiles: section similar to that of here https://github.com/dapr/components-contrib/blob/main/pubsub/kafka/metadata.yaml#L72
| - name: k8sAuthConfigName | ||
| required: false | ||
| description: | | ||
| If using the k8s auth method, specify the name of the k8s auth config. |
There was a problem hiding this comment.
is this referring to ~/.kube/config or a config map? This is not clear to me. Please adjust to be clearer.
There was a problem hiding this comment.
it's a config that includes some metadata the k8s service account jwt used for tokenreview api.
see https://docs.akeyless.io/docs/auth-with-kubernetes#create-kubernetes-gateway-auth-config-using-gateway-serviceaccount.
| example: "eyJ..." | ||
| type: string | ||
| sensitive: true | ||
| - name: k8sAuthConfigName |
| example: "k8s-auth-config" | ||
| type: string | ||
| - name: k8sGatewayUrl | ||
| required: false | ||
| description: | | ||
| The gateway URL that where the k8s auth config is located. | ||
| example: "https://gw.akeyless.svc.cluster.local" | ||
| type: string | ||
| - name: k8sServiceAccountToken | ||
| required: false | ||
| description: | |
| authRequest.SetK8sServiceAccountToken(metadata.K8sServiceAccountToken) | ||
|
|
||
| if metadata.K8SGatewayURL == "" { | ||
| a.logger.Debug("k8s gateway url is missing, using gatewayUrl") |
There was a problem hiding this comment.
| a.logger.Debug("k8s gateway url is missing, using gatewayUrl") | |
| a.logger.Debug("k8s gateway url is missing, using default") |
?
| func parseSecretTypes(secretTypes string) ([]string, error) { | ||
| // Handle "all" or empty string which returns all supported secret types | ||
| if secretTypes == AllSecretTypes || secretTypes == "" { | ||
| return supportedSecretTypes, nil |
There was a problem hiding this comment.
| return supportedSecretTypes, nil | |
| return return append([]string(nil), supportedSecretTypes...), nil |
| return nil, errors.New("no secret types provided") | ||
| } |
There was a problem hiding this comment.
strings.Split returns [""] in an empty case so this is unreachable - pls rm
| } | ||
|
|
||
| // startTokenRefreshRoutine starts a bg goroutine that refreshes the token | ||
| func (a *akeylessSecretStore) startTokenRefreshRoutine(ctx context.Context, metadata *akeylessMetadata) { |
|
|
||
| refreshDuration := time.Until(expiry.Add(-TokenRefreshGracePeriod)) | ||
| if refreshDuration <= 0 { | ||
| refreshDuration = time.Minute // Refresh immediately if less than 1 minute left |
There was a problem hiding this comment.
pls double check with the aws x509 refresher at components-contrib/common/aws/auth/auth_x509.go and make sure the time choice and such you have here aligns nicely
There was a problem hiding this comment.
aws cert refresh is lazy loaded. changed proactive approach to lazy load (store token in secretstore instance, check if valid (> 1m), if not, refresh). simplified flow so secret store apis call sdk directly (rm retry with 401) after token validity check. addressed in 09036f2.
Restructure metadata with authenticationProfiles, set status to alpha, and nest Kubernetes auth fields in akeylessK8sAuth. Signed-off-by: Kobbi Gal <195813801+kgal-akl@users.noreply.github.com> Co-authored-by: Cursor <cursoragent@cursor.com>
Rename constants with prefix-first naming, introduce SecretType and SecretResponse types, simplify stringifyStaticSecret, and split utils.go into auth.go, constants.go, secrets.go, and tls.go. Signed-off-by: Kobbi Gal <195813801+kgal-akl@users.noreply.github.com> Co-authored-by: Cursor <cursoragent@cursor.com>
|
Addressed the remaining
Prior commits on this branch also cover the metadata/README/auth-profile changes, lazy token refresh, and removal of proactive background refresh / Docs PR update is still pending separately. |
|
@sicoyle changes addressed, please review again 🙏 |
|
This pull request has been automatically marked as stale because it has not had activity in the last 30 days. It will be closed in 7 days if no further activity occurs. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions! |
|
@kgal-akl - before I review; could you please address the conflicts! Sorry about this. |
Signed-off-by: kgal-akl <kobbi.g@akeyless.io>
There was a problem hiding this comment.
Pull request overview
Adds a new Akeyless implementation of the Dapr Secret Store component, including client auth handling, TLS support for custom gateway CAs, component metadata/docs, and a comprehensive test suite.
Changes:
- Introduces the
secretstores/akeylesscomponent implementation (auth, secret retrieval, bulk listing, TLS helper, constants). - Adds component docs (
README.md) and component metadata (metadata.yaml) for configuration/auth profiles. - Adds unit/integration-style tests using
httptestplus new Go module dependencies for the Akeyless SDK.
Reviewed changes
Copilot reviewed 9 out of 10 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| secretstores/akeyless/akeyless.go | Main secret store implementation (init/auth, GetSecret, BulkGetSecret, token refresh, list/filter logic). |
| secretstores/akeyless/auth.go | Auth helpers (accessId parsing/type detection, k8s auth config, token expiry parsing). |
| secretstores/akeyless/constants.go | Component constants and supported secret types. |
| secretstores/akeyless/secrets.go | Secret type parsing, static secret stringification, and secret “active” filtering logic. |
| secretstores/akeyless/tls.go | TLS config builder from base64-encoded PEM CA. |
| secretstores/akeyless/akeyless_test.go | Test suite using mock gateways and token refresh coverage. |
| secretstores/akeyless/README.md | End-user documentation and configuration examples. |
| secretstores/akeyless/metadata.yaml | Component metadata schema (fields + auth profiles). |
| go.mod | Adds Akeyless SDK deps; updates Azure SDK versions. |
| go.sum | Dependency checksum updates corresponding to go.mod changes. |
Comments suppressed due to low confidence (1)
secretstores/akeyless/akeyless.go:313
- This inline comment says only static secrets are supported for bulk get, but the code immediately retrieves dynamic and rotated secrets too. Keeping this comment accurate helps prevent future regressions.
// separate items by type since only static secrets are supported for bulk get
staticItemNames, dynamicItemNames, rotatedItemNames := a.separateItemsByType(listItems)
a.logger.Infof("%d items returned (static: %d, dynamic: %d, rotated: %d)", len(listItems), len(staticItemNames), len(dynamicItemNames), len(rotatedItemNames))
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if value, ok := req.Metadata[MetadataKeyPath]; ok { | ||
| // normalize path | ||
| if !strings.HasPrefix(value, "/") { | ||
| secretsPath = "/" + value | ||
| } | ||
|
|
||
| a.logger.Debugf("using path '%s' from metadata...", secretsPath) | ||
| } else { |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: kgal-akl <kobbi.g@akeyless.io>
Description
continuation of #4036.
Issue reference
Please reference the issue this PR will close: #4063
Checklist