Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

set auth alias custom metadata to service account annotations #226

Merged
merged 24 commits into from
Jan 22, 2024

Conversation

thyton
Copy link
Contributor

@thyton thyton commented Jan 2, 2024

Overview

This PR sets auth alias custom metadata to service account annotations. Users can create policy rules that use custom entity/alias metadata and have this metadata be supplied from Kubernetes annotations on the ServiceAccount.

Design of Change

Extra permission configuration for installations is required to allow to get annotations from Kubernetes. A new use_annotations_as_alias_metadata config option is added for users to explicitly opt-in to ensure existing installations still work if this option is opted out.

Only annotations with the prefix vault.hashicorp.com/alias-metadata- of the client token's
associated service account will be added to the auth alias's metadata upon a login request. For example, if an annotation "vault.hashicorp.com/alias-metadata-foo" is configured, "foo" with its value will be added.

NOTE that Vault will need permission to read service accounts from the Kubernetes API.

Example:

# Service Account "default" in "default" namespace
kubectl get serviceaccount default -n default -o json
{
    "apiVersion": "v1",
    "kind": "ServiceAccount",
    "metadata": {
        "annotations": {
            "auth-metadata.vault.hashicorp.com/alias-metadata-bar": "baz",
            "auth-metadata.vault.hashicorp.com/alias-metadata-foo": "bar"
        },
        "creationTimestamp": "2024-01-07T23:27:24Z",
        "name": "default",
        "namespace": "default",
        "resourceVersion": "5514",
        "uid": "ddae5be7-3aaa-4256-adc4-b77ea508e25e"
    }
}


# Configure a role "demo" with bound_service_account_names=default bound_service_account_namespaces=default
vault write auth/kubernetes/role/demo bound_service_account_names=default bound_service_account_namespaces=default policies=default ttl=1h
Success! Data written to: auth/kubernetes/role/demo


# Login request to vault.
vault write auth/kubernetes/login role=demo jwt=$(kubectl create token -n default default)
Key                                       Value
---                                       -----
token                                     hvs.CAESIAD96sjSFtZU6BXo5E1SuPoXcb_M_PJ9CSs0fM4OEcVMGh4KHGh2cy5kdTJid1JUeDRPZ3dXOVYzUTQxS3Zkc1Q
token_accessor                            FNQlfHrY2ioNmsKiX4EqACjJ
token_duration                            1h
token_renewable                           true
token_policies                            ["default"]
identity_policies                         []
policies                                  ["default"]
token_meta_role                           demo
token_meta_service_account_name           default
token_meta_service_account_namespace      default
token_meta_service_account_secret_name    n/a
token_meta_service_account_uid            ddae5be7-3aaa-4256-adc4-b77ea508e25e


# A new entity alias was created
vault list identity/entity-alias/id 
Keys
----
c474b739-f5d7-9b42-a8ea-d192972d832d

# The entity alias is expected to have the customized key value pairs from the SA annotations together with other pairs for vault internal use.
vault read identity/entity-alias/id/c474b739-f5d7-9b42-a8ea-d192972d832d
Key                          Value
---                          -----
canonical_id                 7281fda9-12c3-66aa-43d1-8e9817731d26
creation_time                2024-01-08T00:47:57.77138992Z
custom_metadata              <nil>
id                           c474b739-f5d7-9b42-a8ea-d192972d832d
last_update_time             2024-01-08T00:47:57.77138992Z
local                        false
merged_from_canonical_ids    <nil>
metadata                     map[foo:bar bar:baz service_account_name:default service_account_namespace:default service_account_secret_name: service_account_uid:ddae5be7-3aaa-4256-adc4-b77ea508e25e]
mount_accessor               auth_kubernetes-dev_6c913879
mount_path                   auth/kubernetes/
mount_type                   kubernetes-dev
name                         ddae5be7-3aaa-4256-adc4-b77ea508e25e
namespace_id                 root

Related Issues/Pull Requests

Contributor Checklist

  • Add relevant docs to upstream Vault repository, or sufficient reasoning why docs won’t be added yet
    My Docs PR vault #24941 Link
  • Add output for any tests not ran in CI to the PR description (eg, acceptance tests)
  • Backwards compatible

@thyton thyton marked this pull request as draft January 2, 2024 09:12
Copy link
Contributor

@tomhjp tomhjp left a comment

Choose a reason for hiding this comment

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

Looking good! Not a complete review, but I left a couple of minor WIP thoughts


// Use the configured TokenReviewer JWT as the bearer
if w.config.TokenReviewerJWT == "" {
return nil, errors.New("service account lookup failed: TokenReviewer JWT needs to be configured to retrieve service accounts")
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there any reason we can't use the client's own token like we do for other API requests? It's not my favourite feature, but I would favour consistency and shared code to achieve that if possible.

@thyton thyton marked this pull request as ready for review January 8, 2024 08:47
Copy link
Contributor

@tomhjp tomhjp left a comment

Choose a reason for hiding this comment

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

Generally LGTM - I think there is one major issue with backwards compatibility, but the remaining comments are minor suggestions/questions

@thyton thyton requested a review from tomhjp January 18, 2024 17:58
Copy link
Contributor

@tomhjp tomhjp left a comment

Choose a reason for hiding this comment

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

The test looks great! I left a few nits and style comments, but I think there is 1 bug that is worth addressing.

backend.go Outdated
// Note Vault client or the token reviewer service account needs
// to be configured with the permission to get service account
// annotations from Kubernetes API
useAnnotationsAsAliasMetadata bool
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this should be a member of kubeConfig instead. The lifecycle of fields in kubeAuthBackend matches the lifecycle of the plugin process, but this value is tied to the most recent write to the config endpoint instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank you for pointing this out!

t.Fatalf("Expected to enable kv secrets engine but got: %v", err)
}

cleanup := func() {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this can probably be simplified with t.Cleanup too?

@thyton thyton requested a review from tomhjp January 19, 2024 03:03
Copy link
Contributor

@tomhjp tomhjp left a comment

Choose a reason for hiding this comment

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

LGTM! 🎉

Co-authored-by: Tom Proctor <[email protected]>
… github.com:hashicorp/vault-plugin-auth-kubernetes into VAULT-1665-add-custom-metadata-from-k8s-annotations
@thyton thyton merged commit daeaf8d into main Jan 22, 2024
8 checks passed
@thyton thyton deleted the VAULT-1665-add-custom-metadata-from-k8s-annotations branch January 22, 2024 19:56
@thyton thyton linked an issue Feb 19, 2024 that may be closed by this pull request
@awnumar
Copy link

awnumar commented Feb 17, 2025

👋🏽 Just wanted to point out for future readers: the example service account is incorrect: its annotations have a auth-metadata. prefix.

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.

Add custom metadata to Vault from ServiceAccount annotations
3 participants