Put alias_metadata tokenutil field into public SDK (#11468) (#11717)

This commit is contained in:
Vault Automation 2026-01-13 07:43:33 -08:00 committed by GitHub
parent c9c1b158c8
commit 3fde566dd2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 123 additions and 35 deletions

View file

@ -10,6 +10,7 @@ import (
"time"
"github.com/hashicorp/vault/sdk/logical"
"github.com/stretchr/testify/require"
)
func TestAppRole_BoundCIDRLogin(t *testing.T) {
@ -358,3 +359,90 @@ func TestAppRole_RoleDoesNotExist(t *testing.T) {
t.Fatalf("Error was not due to invalid role ID. Error: %s", errString)
}
}
// TestAppRole_RoleLogin_AliasMetadata tests that the alias metadata is correctly set
// in the role and that it is returned in the login response.
func TestAppRole_RoleLogin_AliasMetadata(t *testing.T) {
b, storage := createBackendWithStorage(t)
metadata := map[string]string{
"key1": "value1",
"key2": "value2",
}
// Create a role with token auth metadata
{
roleData := map[string]interface{}{
"policies": "a,b,c",
"alias_metadata": metadata,
}
req := &logical.Request{
Operation: logical.CreateOperation,
Path: "role/role1",
Storage: storage,
Data: roleData,
}
_ = b.requestNoErr(t, req)
}
// Assert that the role was created with the correct metadata
{
roleRoleIDReq := &logical.Request{
Operation: logical.ReadOperation,
Path: "role/role1",
Storage: storage,
}
resp := b.requestNoErr(t, roleRoleIDReq)
require.Equal(t, metadata, resp.Data["alias_metadata"])
}
// Get the role ID
var roleID any
{
roleRoleIDReq := &logical.Request{
Operation: logical.ReadOperation,
Path: "role/role1/role-id",
Storage: storage,
}
resp := b.requestNoErr(t, roleRoleIDReq)
roleID = resp.Data["role_id"]
}
// Get the secret ID
var secretID any
{
roleSecretIDReq := &logical.Request{
Operation: logical.UpdateOperation,
Path: "role/role1/secret-id",
Storage: storage,
}
resp := b.requestNoErr(t, roleSecretIDReq)
secretID = resp.Data["secret_id"]
}
// Login
{
loginData := map[string]interface{}{
"role_id": roleID,
"secret_id": secretID,
}
loginReq := &logical.Request{
Operation: logical.UpdateOperation,
Path: "login",
Storage: storage,
Data: loginData,
Connection: &logical.Connection{
RemoteAddr: "127.0.0.1",
},
}
loginResp, err := b.HandleRequest(context.Background(), loginReq)
require.NoError(t, err)
require.False(t, loginResp.IsError())
require.NotNil(t, loginResp.Auth, "expected a non-nil auth object in the response")
require.Equal(t, metadata, loginResp.Auth.Alias.CustomMetadata)
}
}

View file

@ -14,7 +14,6 @@ import (
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/go-secure-stdlib/awsutil"
"github.com/hashicorp/go-secure-stdlib/strutil"
"github.com/hashicorp/vault/helper/constants"
vlttesting "github.com/hashicorp/vault/helper/testhelpers/logical"
"github.com/hashicorp/vault/sdk/helper/logging"
"github.com/hashicorp/vault/sdk/helper/policyutil"
@ -603,6 +602,7 @@ func TestAwsEc2_RoleCrud(t *testing.T) {
}
expected := map[string]interface{}{
"alias_metadata": map[string]string{},
"auth_type": ec2AuthType,
"bound_ami_id": []string{"testamiid"},
"bound_account_id": []string{"testaccountid"},
@ -635,10 +635,6 @@ func TestAwsEc2_RoleCrud(t *testing.T) {
"token_type": "default",
}
if constants.IsEnterprise {
expected["alias_metadata"] = map[string]string{}
}
if resp.Data["role_id"] == nil {
t.Fatal("role_id not found in response")
}

View file

@ -16,7 +16,6 @@ import (
"github.com/go-test/deep"
hclog "github.com/hashicorp/go-hclog"
"github.com/hashicorp/go-secure-stdlib/strutil"
"github.com/hashicorp/vault/helper/constants"
"github.com/hashicorp/vault/helper/namespace"
"github.com/hashicorp/vault/helper/testhelpers/ldap"
logicaltest "github.com/hashicorp/vault/helper/testhelpers/logical"
@ -1522,6 +1521,7 @@ func TestLdapAuthBackend_ConfigUpgrade(t *testing.T) {
TokenParams: tokenutil.TokenParams{
TokenPeriod: 5 * time.Minute,
TokenExplicitMaxTTL: 24 * time.Hour,
AliasMetadata: make(map[string]string),
},
ConfigEntry: &ldaputil.ConfigEntry{
Url: cfg.Url,
@ -1545,9 +1545,6 @@ func TestLdapAuthBackend_ConfigUpgrade(t *testing.T) {
MaximumPageSize: 1000,
},
}
if constants.IsEnterprise {
exp.TokenParams.AliasMetadata = make(map[string]string)
}
configEntry, err := b.Config(ctx, configReq)
if err != nil {

3
changelog/_11468.txt Normal file
View file

@ -0,0 +1,3 @@
```release-note:improvement
sdk: Add alias_metadata to tokenutil fields that auth method roles use.
```

View file

@ -76,7 +76,7 @@ func AddTokenFieldsWithAllowList(m map[string]*framework.FieldSchema, allowed []
// TokenFields provides a set of field schemas for the parameters
func TokenFields() map[string]*framework.FieldSchema {
return entTokenFields(map[string]*framework.FieldSchema{
return map[string]*framework.FieldSchema{
"token_bound_cidrs": {
Type: framework.TypeCommaStringSlice,
Description: `Comma separated string or JSON list of CIDR blocks. If set, specifies the blocks of IP addresses which are allowed to use the generated token.`,
@ -160,7 +160,16 @@ func TokenFields() map[string]*framework.FieldSchema {
Group: "Tokens",
},
},
})
"alias_metadata": {
Type: framework.TypeKVPairs,
Description: "The metadata to be tied to generated entity alias. This should be a list or map containing the metadata in key value pairs",
DisplayAttrs: &framework.DisplayAttributes{
Name: "Token Alias Metadata",
Group: "Tokens",
},
},
}
}
// ParseTokenFields provides common field parsing functionality into a TokenFields struct
@ -241,7 +250,10 @@ func (t *TokenParams) ParseTokenFields(req *logical.Request, d *framework.FieldD
return errors.New("'token_ttl' cannot be greater than 'token_max_ttl'")
}
t.entParseTokenFields(d)
t.AliasMetadata = make(map[string]string)
if tokenMetadataRaw, ok := d.GetOk("alias_metadata"); ok {
t.AliasMetadata = tokenMetadataRaw.(map[string]string)
}
return nil
}
@ -266,7 +278,10 @@ func (t *TokenParams) PopulateTokenData(m map[string]interface{}) {
m["token_bound_cidrs"] = []string{}
}
t.entPopulateTokenData(m)
m["alias_metadata"] = map[string]string{}
if len(t.AliasMetadata) > 0 {
m["alias_metadata"] = t.AliasMetadata
}
}
// PopulateTokenAuth populates Auth with parameters
@ -282,7 +297,17 @@ func (t *TokenParams) PopulateTokenAuth(auth *logical.Auth) {
auth.TTL = t.TokenTTL
auth.NumUses = t.TokenNumUses
t.entPopulateTokenAuth(auth)
if len(t.AliasMetadata) > 0 && auth.Alias != nil {
if auth.Alias.CustomMetadata == nil {
auth.Alias.CustomMetadata = map[string]string{}
}
for k, v := range t.AliasMetadata {
if _, ok := auth.Alias.CustomMetadata[k]; !ok {
// Do not override metadata with the same key added by the caller
auth.Alias.CustomMetadata[k] = v
}
}
}
}
func DeprecationText(param string) string {

View file

@ -1,21 +0,0 @@
// Copyright IBM Corp. 2016, 2025
// SPDX-License-Identifier: MPL-2.0
//go:build !enterprise
package tokenutil
import (
"github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/vault/sdk/logical"
)
func entTokenFields(fields map[string]*framework.FieldSchema) map[string]*framework.FieldSchema {
return fields
}
func (t *TokenParams) entParseTokenFields(d *framework.FieldData) {}
func (t *TokenParams) entPopulateTokenData(m map[string]any) {}
func (t *TokenParams) entPopulateTokenAuth(auth *logical.Auth) {}