mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-11-02 03:27:54 +00:00
Add AliCloud auth to the Vault Agent (#5179)
This commit is contained in:
committed by
Jeff Mitchell
parent
f5c712f52a
commit
d69c674c8e
@@ -16,6 +16,7 @@ import (
|
||||
"github.com/hashicorp/errwrap"
|
||||
log "github.com/hashicorp/go-hclog"
|
||||
"github.com/hashicorp/vault/command/agent/auth"
|
||||
"github.com/hashicorp/vault/command/agent/auth/alicloud"
|
||||
"github.com/hashicorp/vault/command/agent/auth/aws"
|
||||
"github.com/hashicorp/vault/command/agent/auth/azure"
|
||||
"github.com/hashicorp/vault/command/agent/auth/gcp"
|
||||
@@ -284,6 +285,8 @@ func (c *AgentCommand) Run(args []string) int {
|
||||
Config: config.AutoAuth.Method.Config,
|
||||
}
|
||||
switch config.AutoAuth.Method.Type {
|
||||
case "alicloud":
|
||||
method, err = alicloud.NewAliCloudAuthMethod(authConfig)
|
||||
case "aws":
|
||||
method, err = aws.NewAWSAuthMethod(authConfig)
|
||||
case "azure":
|
||||
|
||||
213
command/agent/alicloud_end_to_end_test.go
Normal file
213
command/agent/alicloud_end_to_end_test.go
Normal file
@@ -0,0 +1,213 @@
|
||||
package agent
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk"
|
||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
|
||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/providers"
|
||||
"github.com/aliyun/alibaba-cloud-sdk-go/services/sts"
|
||||
"github.com/hashicorp/go-hclog"
|
||||
"github.com/hashicorp/go-uuid"
|
||||
vaultalicloud "github.com/hashicorp/vault-plugin-auth-alicloud"
|
||||
"github.com/hashicorp/vault/api"
|
||||
"github.com/hashicorp/vault/command/agent/auth"
|
||||
agentalicloud "github.com/hashicorp/vault/command/agent/auth/alicloud"
|
||||
"github.com/hashicorp/vault/command/agent/sink"
|
||||
"github.com/hashicorp/vault/command/agent/sink/file"
|
||||
"github.com/hashicorp/vault/helper/logging"
|
||||
vaulthttp "github.com/hashicorp/vault/http"
|
||||
"github.com/hashicorp/vault/logical"
|
||||
"github.com/hashicorp/vault/vault"
|
||||
)
|
||||
|
||||
const (
|
||||
envVarRunAccTests = "VAULT_ACC"
|
||||
envVarAccessKey = "ALICLOUD_TEST_ACCESS_KEY"
|
||||
envVarSecretKey = "ALICLOUD_TEST_SECRET_KEY"
|
||||
envVarRoleArn = "ALICLOUD_TEST_ROLE_ARN"
|
||||
)
|
||||
|
||||
var runAcceptanceTests = os.Getenv(envVarRunAccTests) == "1"
|
||||
|
||||
func TestAliCloudEndToEnd(t *testing.T) {
|
||||
if !runAcceptanceTests {
|
||||
t.SkipNow()
|
||||
}
|
||||
|
||||
logger := logging.NewVaultLogger(hclog.Trace)
|
||||
coreConfig := &vault.CoreConfig{
|
||||
Logger: logger,
|
||||
CredentialBackends: map[string]logical.Factory{
|
||||
"alicloud": vaultalicloud.Factory,
|
||||
},
|
||||
}
|
||||
cluster := vault.NewTestCluster(t, coreConfig, &vault.TestClusterOptions{
|
||||
HandlerFunc: vaulthttp.Handler,
|
||||
})
|
||||
cluster.Start()
|
||||
defer cluster.Cleanup()
|
||||
|
||||
vault.TestWaitActive(t, cluster.Cores[0].Core)
|
||||
client := cluster.Cores[0].Client
|
||||
|
||||
// Setup Vault
|
||||
if err := client.Sys().EnableAuthWithOptions("alicloud", &api.EnableAuthOptions{
|
||||
Type: "alicloud",
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if _, err := client.Logical().Write("auth/alicloud/role/test", map[string]interface{}{
|
||||
"arn": os.Getenv(envVarRoleArn),
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ctx, cancelFunc := context.WithCancel(context.Background())
|
||||
timer := time.AfterFunc(30*time.Second, func() {
|
||||
cancelFunc()
|
||||
})
|
||||
defer timer.Stop()
|
||||
|
||||
// We're going to feed alicloud auth creds via env variables.
|
||||
if err := setAliCloudEnvCreds(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer func() {
|
||||
if err := unsetAliCloudEnvCreds(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}()
|
||||
|
||||
am, err := agentalicloud.NewAliCloudAuthMethod(&auth.AuthConfig{
|
||||
Logger: logger.Named("auth.alicloud"),
|
||||
MountPath: "auth/alicloud",
|
||||
Config: map[string]interface{}{
|
||||
"role": "test",
|
||||
"region": "us-west-1",
|
||||
"cred_check_freq_seconds": 1,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ahConfig := &auth.AuthHandlerConfig{
|
||||
Logger: logger.Named("auth.handler"),
|
||||
Client: client,
|
||||
}
|
||||
|
||||
ah := auth.NewAuthHandler(ahConfig)
|
||||
go ah.Run(ctx, am)
|
||||
defer func() {
|
||||
<-ah.DoneCh
|
||||
}()
|
||||
|
||||
tmpFile, err := ioutil.TempFile("", "auth.tokensink.test.")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
tokenSinkFileName := tmpFile.Name()
|
||||
tmpFile.Close()
|
||||
os.Remove(tokenSinkFileName)
|
||||
t.Logf("output: %s", tokenSinkFileName)
|
||||
|
||||
config := &sink.SinkConfig{
|
||||
Logger: logger.Named("sink.file"),
|
||||
Config: map[string]interface{}{
|
||||
"path": tokenSinkFileName,
|
||||
},
|
||||
WrapTTL: 10 * time.Second,
|
||||
}
|
||||
|
||||
fs, err := file.NewFileSink(config)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
config.Sink = fs
|
||||
|
||||
ss := sink.NewSinkServer(&sink.SinkServerConfig{
|
||||
Logger: logger.Named("sink.server"),
|
||||
Client: client,
|
||||
})
|
||||
go ss.Run(ctx, ah.OutputCh, []*sink.SinkConfig{config})
|
||||
defer func() {
|
||||
<-ss.DoneCh
|
||||
}()
|
||||
|
||||
if stat, err := os.Lstat(tokenSinkFileName); err == nil {
|
||||
t.Fatalf("expected err but got %s", stat)
|
||||
} else if !os.IsNotExist(err) {
|
||||
t.Fatal("expected notexist err")
|
||||
}
|
||||
|
||||
// Wait 2 seconds for the env variables to be detected and an auth to be generated.
|
||||
time.Sleep(time.Second * 2)
|
||||
|
||||
token, err := readToken(tokenSinkFileName)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if token.Token == "" {
|
||||
t.Fatal("expected token but didn't receive it")
|
||||
}
|
||||
}
|
||||
|
||||
func readToken(fileName string) (*logical.HTTPWrapInfo, error) {
|
||||
b, err := ioutil.ReadFile(fileName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
wrapper := &logical.HTTPWrapInfo{}
|
||||
if err := json.NewDecoder(bytes.NewReader(b)).Decode(wrapper); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return wrapper, nil
|
||||
}
|
||||
|
||||
func setAliCloudEnvCreds() error {
|
||||
config := sdk.NewConfig()
|
||||
config.Scheme = "https"
|
||||
client, err := sts.NewClientWithOptions("us-west-1", config, credentials.NewAccessKeyCredential(os.Getenv(envVarAccessKey), os.Getenv(envVarSecretKey)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
roleSessionName, err := uuid.GenerateUUID()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
assumeRoleReq := sts.CreateAssumeRoleRequest()
|
||||
assumeRoleReq.RoleArn = os.Getenv(envVarRoleArn)
|
||||
assumeRoleReq.RoleSessionName = strings.Replace(roleSessionName, "-", "", -1)
|
||||
assumeRoleResp, err := client.AssumeRole(assumeRoleReq)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := os.Setenv(providers.EnvVarAccessKeyID, assumeRoleResp.Credentials.AccessKeyId); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.Setenv(providers.EnvVarAccessKeySecret, assumeRoleResp.Credentials.AccessKeySecret); err != nil {
|
||||
return err
|
||||
}
|
||||
return os.Setenv(providers.EnvVarAccessKeyStsToken, assumeRoleResp.Credentials.SecurityToken)
|
||||
}
|
||||
|
||||
func unsetAliCloudEnvCreds() error {
|
||||
if err := os.Unsetenv(providers.EnvVarAccessKeyID); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.Unsetenv(providers.EnvVarAccessKeySecret); err != nil {
|
||||
return err
|
||||
}
|
||||
return os.Unsetenv(providers.EnvVarAccessKeyStsToken)
|
||||
}
|
||||
233
command/agent/auth/alicloud/alicloud.go
Normal file
233
command/agent/auth/alicloud/alicloud.go
Normal file
@@ -0,0 +1,233 @@
|
||||
package alicloud
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
aliCloudAuth "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth"
|
||||
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials/providers"
|
||||
"github.com/hashicorp/go-hclog"
|
||||
"github.com/hashicorp/vault-plugin-auth-alicloud/tools"
|
||||
"github.com/hashicorp/vault/api"
|
||||
"github.com/hashicorp/vault/command/agent/auth"
|
||||
)
|
||||
|
||||
/*
|
||||
|
||||
Creds can be inferred from instance metadata, and those creds
|
||||
expire every 60 minutes, so we're going to need to poll for new
|
||||
creds. Since we're polling anyways, let's poll once a minute so
|
||||
all changes can be picked up rather quickly. This is configurable,
|
||||
however.
|
||||
|
||||
*/
|
||||
const defaultCredCheckFreqSeconds = 60
|
||||
|
||||
func NewAliCloudAuthMethod(conf *auth.AuthConfig) (auth.AuthMethod, error) {
|
||||
if conf == nil {
|
||||
return nil, errors.New("empty config")
|
||||
}
|
||||
if conf.Config == nil {
|
||||
return nil, errors.New("empty config data")
|
||||
}
|
||||
|
||||
a := &alicloudMethod{
|
||||
logger: conf.Logger,
|
||||
mountPath: conf.MountPath,
|
||||
credsFound: make(chan struct{}),
|
||||
stopCh: make(chan struct{}),
|
||||
}
|
||||
|
||||
// Build the required information we'll need to create a client.
|
||||
if roleRaw, ok := conf.Config["role"]; !ok {
|
||||
return nil, errors.New("'role' is required but is not provided")
|
||||
} else {
|
||||
if a.role, ok = roleRaw.(string); !ok {
|
||||
return nil, errors.New("could not convert 'role' config value to string")
|
||||
}
|
||||
}
|
||||
if regionRaw, ok := conf.Config["region"]; !ok {
|
||||
return nil, errors.New("'region' is required but is not provided")
|
||||
} else {
|
||||
if a.region, ok = regionRaw.(string); !ok {
|
||||
return nil, errors.New("could not convert 'region' config value to string")
|
||||
}
|
||||
}
|
||||
|
||||
// Check for an optional custom frequency at which we should poll for creds.
|
||||
credCheckFreqSec := defaultCredCheckFreqSeconds
|
||||
if checkFreqRaw, ok := conf.Config["cred_check_freq_seconds"]; ok {
|
||||
if credFreq, ok := checkFreqRaw.(int); ok {
|
||||
credCheckFreqSec = credFreq
|
||||
}
|
||||
}
|
||||
|
||||
// Build the optional, configuration-based piece of the credential chain.
|
||||
credConfig := &providers.Configuration{}
|
||||
|
||||
if accessKeyRaw, ok := conf.Config["access_key"]; ok {
|
||||
if credConfig.AccessKeyID, ok = accessKeyRaw.(string); !ok {
|
||||
return nil, errors.New("could not convert 'access_key' config value to string")
|
||||
}
|
||||
}
|
||||
|
||||
if accessSecretRaw, ok := conf.Config["access_secret"]; ok {
|
||||
if credConfig.AccessKeySecret, ok = accessSecretRaw.(string); !ok {
|
||||
return nil, errors.New("could not convert 'access_secret' config value to string")
|
||||
}
|
||||
}
|
||||
|
||||
if accessTokenRaw, ok := conf.Config["access_token"]; ok {
|
||||
if credConfig.AccessKeyStsToken, ok = accessTokenRaw.(string); !ok {
|
||||
return nil, errors.New("could not convert 'access_token' config value to string")
|
||||
}
|
||||
}
|
||||
|
||||
if roleArnRaw, ok := conf.Config["role_arn"]; ok {
|
||||
if credConfig.RoleArn, ok = roleArnRaw.(string); !ok {
|
||||
return nil, errors.New("could not convert 'role_arn' config value to string")
|
||||
}
|
||||
}
|
||||
|
||||
if roleSessionNameRaw, ok := conf.Config["role_session_name"]; ok {
|
||||
if credConfig.RoleSessionName, ok = roleSessionNameRaw.(string); !ok {
|
||||
return nil, errors.New("could not convert 'role_session_name' config value to string")
|
||||
}
|
||||
}
|
||||
|
||||
if roleSessionExpirationRaw, ok := conf.Config["role_session_expiration"]; ok {
|
||||
if roleSessionExpiration, ok := roleSessionExpirationRaw.(int); !ok {
|
||||
return nil, errors.New("could not convert 'role_session_expiration' config value to int")
|
||||
} else {
|
||||
credConfig.RoleSessionExpiration = &roleSessionExpiration
|
||||
}
|
||||
}
|
||||
|
||||
if privateKeyRaw, ok := conf.Config["private_key"]; ok {
|
||||
if credConfig.PrivateKey, ok = privateKeyRaw.(string); !ok {
|
||||
return nil, errors.New("could not convert 'private_key' config value to string")
|
||||
}
|
||||
}
|
||||
|
||||
if publicKeyIdRaw, ok := conf.Config["public_key_id"]; ok {
|
||||
if credConfig.PublicKeyID, ok = publicKeyIdRaw.(string); !ok {
|
||||
return nil, errors.New("could not convert 'public_key_id' config value to string")
|
||||
}
|
||||
}
|
||||
|
||||
if sessionExpirationRaw, ok := conf.Config["session_expiration"]; ok {
|
||||
if sessionExpiration, ok := sessionExpirationRaw.(int); !ok {
|
||||
return nil, errors.New("could not convert 'session_expiration' config value to int")
|
||||
} else {
|
||||
credConfig.SessionExpiration = &sessionExpiration
|
||||
}
|
||||
}
|
||||
|
||||
if roleNameRaw, ok := conf.Config["role_name"]; ok {
|
||||
if credConfig.RoleName, ok = roleNameRaw.(string); !ok {
|
||||
return nil, errors.New("could not convert 'role_name' config value to string")
|
||||
}
|
||||
}
|
||||
|
||||
credentialChain := []providers.Provider{
|
||||
providers.NewEnvCredentialProvider(),
|
||||
providers.NewConfigurationCredentialProvider(credConfig),
|
||||
providers.NewInstanceMetadataProvider(),
|
||||
}
|
||||
credProvider := providers.NewChainProvider(credentialChain)
|
||||
|
||||
// Do an initial population of the creds because we want to err right away if we can't
|
||||
// even get a first set.
|
||||
lastCreds, err := credProvider.Retrieve()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
a.lastCreds = lastCreds
|
||||
|
||||
go a.pollForCreds(credProvider, credCheckFreqSec)
|
||||
|
||||
return a, nil
|
||||
}
|
||||
|
||||
type alicloudMethod struct {
|
||||
logger hclog.Logger
|
||||
mountPath string
|
||||
|
||||
// These parameters are fed into building login data.
|
||||
role string
|
||||
region string
|
||||
|
||||
// These are used to share the latest creds safely across goroutines.
|
||||
credLock sync.Mutex
|
||||
lastCreds aliCloudAuth.Credential
|
||||
|
||||
// Notifies the outer environment that it should call Authenticate again.
|
||||
credsFound chan struct{}
|
||||
|
||||
// Detects that the outer environment is closing.
|
||||
stopCh chan struct{}
|
||||
}
|
||||
|
||||
func (a *alicloudMethod) Authenticate(context.Context, *api.Client) (string, map[string]interface{}, error) {
|
||||
a.credLock.Lock()
|
||||
defer a.credLock.Unlock()
|
||||
|
||||
a.logger.Trace("beginning authentication")
|
||||
data, err := tools.GenerateLoginData(a.role, a.lastCreds, a.region)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
return fmt.Sprintf("%s/login", a.mountPath), data, nil
|
||||
}
|
||||
|
||||
func (a *alicloudMethod) NewCreds() chan struct{} {
|
||||
return a.credsFound
|
||||
}
|
||||
|
||||
func (a *alicloudMethod) CredSuccess() {}
|
||||
|
||||
func (a *alicloudMethod) Shutdown() {
|
||||
close(a.credsFound)
|
||||
close(a.stopCh)
|
||||
}
|
||||
|
||||
func (a *alicloudMethod) pollForCreds(credProvider providers.Provider, frequencySeconds int) {
|
||||
ticker := time.NewTicker(time.Duration(frequencySeconds) * time.Second)
|
||||
defer ticker.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-a.stopCh:
|
||||
a.logger.Trace("shutdown triggered, stopping alicloud auth handler")
|
||||
return
|
||||
case <-ticker.C:
|
||||
if err := a.checkCreds(credProvider); err != nil {
|
||||
a.logger.Warn("unable to retrieve current creds, retaining last creds", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (a *alicloudMethod) checkCreds(credProvider providers.Provider) error {
|
||||
a.credLock.Lock()
|
||||
defer a.credLock.Unlock()
|
||||
|
||||
a.logger.Trace("checking for new credentials")
|
||||
currentCreds, err := credProvider.Retrieve()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// These will always have different pointers regardless of whether their
|
||||
// values are identical, hence the use of DeepEqual.
|
||||
if reflect.DeepEqual(currentCreds, a.lastCreds) {
|
||||
a.logger.Trace("credentials are unchanged")
|
||||
return nil
|
||||
}
|
||||
a.lastCreds = currentCreds
|
||||
a.logger.Trace("new credentials detected, triggering Authenticate")
|
||||
a.credsFound <- struct{}{}
|
||||
return nil
|
||||
}
|
||||
2
vendor/github.com/hashicorp/vault-plugin-auth-alicloud/path_login.go
generated
vendored
2
vendor/github.com/hashicorp/vault-plugin-auth-alicloud/path_login.go
generated
vendored
@@ -114,7 +114,7 @@ func (b *backend) pathLoginUpdate(ctx context.Context, req *logical.Request, dat
|
||||
"identity_type": callerIdentity.IdentityType,
|
||||
"principal_id": callerIdentity.PrincipalId,
|
||||
"request_id": callerIdentity.RequestId,
|
||||
"role_name": parsedARN.RoleName,
|
||||
"role_name": roleName,
|
||||
},
|
||||
DisplayName: callerIdentity.PrincipalId,
|
||||
LeaseOptions: logical.LeaseOptions{
|
||||
|
||||
6
vendor/vendor.json
vendored
6
vendor/vendor.json
vendored
@@ -1351,10 +1351,10 @@
|
||||
"revisionTime": "2018-05-30T15:59:58Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "76udfjuAEmd4JFZP8LhTLTKZ6gk=",
|
||||
"checksumSHA1": "pqkqaBRFKL2P/64xpuxj/3J/+sQ=",
|
||||
"path": "github.com/hashicorp/vault-plugin-auth-alicloud",
|
||||
"revision": "90acf238c385792939aade0286fcb941d9899435",
|
||||
"revisionTime": "2018-08-22T21:26:04Z"
|
||||
"revision": "1a078292f70a4c9e366a13d3c725d105bd5be1af",
|
||||
"revisionTime": "2018-09-04T20:26:51Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "xdrSQoX7B7Hr4iWm9T2+5wHVpHQ=",
|
||||
|
||||
62
website/source/docs/agent/autoauth/methods/alicloud.html.md
Normal file
62
website/source/docs/agent/autoauth/methods/alicloud.html.md
Normal file
@@ -0,0 +1,62 @@
|
||||
---
|
||||
layout: "docs"
|
||||
page_title: "Vault Agent Auto-Auth AliCloud Method"
|
||||
sidebar_current: "docs-agent-autoauth-methods-alicloud"
|
||||
description: |-
|
||||
AliCloud Method for Vault Agent Auto-Auth
|
||||
---
|
||||
|
||||
# Vault Agent Auto-Auth AliCloud Method
|
||||
|
||||
The `alicloud` method performs authentication against the [AliCloud Auth
|
||||
method](https://www.vaultproject.io/docs/auth/alicloud.html).
|
||||
|
||||
## Credentials
|
||||
|
||||
The Vault agent will use the first credential it can successfully obtain in the following order:
|
||||
|
||||
1. [Env variables](https://github.com/aliyun/alibaba-cloud-sdk-go/blob/master/sdk/auth/credentials/providers/env.go)
|
||||
2. A static credential configuration
|
||||
3. Instance metadata (recommended)
|
||||
|
||||
Wherever possible, we recommend using instance metadata for credentials. These rotate every hour
|
||||
and require no effort on your part to provision, making instance metadata the most secure of the three methods. If
|
||||
using instance metadata _and_ a custom `cred_check_freq_seconds`, be sure the frequency is set for
|
||||
less than an hour, because instance metadata credentials expire every hour.
|
||||
|
||||
Environment variables are given first precedence to provide the ability to quickly override your
|
||||
configuration.
|
||||
|
||||
## Configuration
|
||||
|
||||
### General
|
||||
|
||||
- `role` `(string: required)` - The role to authenticate against on Vault.
|
||||
|
||||
- `region` `(string: required)` - The AliCloud region in which the Vault agent resides. Example: "us-west-1".
|
||||
|
||||
- `cred_check_freq_seconds` `(integer: optional)` - In seconds, how frequently the Vault agent should check for new credentials.
|
||||
|
||||
### Optional Static Credential Configuration (Not Preferred)
|
||||
|
||||
If instance metadata is not available, you may provide credential information through the parameters below.
|
||||
|
||||
- `access_key` `(string: optional)` - The access key to use.
|
||||
|
||||
- `secret_key` `(string: optional)` - The secret key to use.
|
||||
|
||||
- `access_token` `(string: optional)` - The access token to use.
|
||||
|
||||
- `role_arn` `(string: optional)` - The role ARN to use.
|
||||
|
||||
- `role_session_name` `(string: optional)` - The role session name to use.
|
||||
|
||||
- `role_session_expiration` `(string: optional)` - The role session expiration to use.
|
||||
|
||||
- `private_key` `(string: optional)` - The private key to use.
|
||||
|
||||
- `public_key_id` `(string: optional)` - The public key ID to use.
|
||||
|
||||
- `session_expiration` `(string: optional)` - The session expiration to use.
|
||||
|
||||
- `role_name` `(string: optional)` - The role name to use.
|
||||
@@ -383,6 +383,9 @@
|
||||
<li<%= sidebar_current("docs-agent-autoauth-methods") %>>
|
||||
<a href="/docs/agent/autoauth/methods/index.html">Methods</a>
|
||||
<ul class="nav">
|
||||
<li<%= sidebar_current("docs-agent-autoauth-methods-alicloud") %>>
|
||||
<a href="/docs/agent/autoauth/methods/alicloud.html">AliCloud</a>
|
||||
</li>
|
||||
<li<%= sidebar_current("docs-agent-autoauth-methods-aws") %>>
|
||||
<a href="/docs/agent/autoauth/methods/aws.html">AWS</a>
|
||||
</li>
|
||||
|
||||
Reference in New Issue
Block a user