Package: github.com/aws/aws-sdk-go-v2/credentials/stscreds
The stscreds package provides credential providers for retrieving temporary AWS credentials using STS (Security Token Service) for assuming roles and web identity federation. This enables cross-account access and federated identity scenarios.
import (
"github.com/aws/aws-sdk-go-v2/credentials/stscreds"
"github.com/aws/aws-sdk-go-v2/service/sts"
)The stscreds package provides two primary credential providers:
Important: These providers are not safe for concurrent use. Wrap them with aws.CredentialsCache to provide concurrency safety and credential caching.
package main
import (
"context"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/credentials/stscreds"
"github.com/aws/aws-sdk-go-v2/service/sts"
"github.com/aws/aws-sdk-go-v2/service/s3"
)
func main() {
// Create STS client
stsClient := sts.NewFromConfig(cfg)
// Create assume role provider
provider := stscreds.NewAssumeRoleProvider(
stsClient,
"arn:aws:iam::ACCOUNT-ID:role/RoleName",
)
// Wrap with CredentialsCache for concurrency safety
credentials := aws.NewCredentialsCache(provider)
// Use with AWS service clients
config := aws.Config{
Region: "us-east-1",
Credentials: credentials,
}
client := s3.NewFromConfig(config)
// Use client
}package main
import (
"github.com/aws/aws-sdk-go-v2/credentials/stscreds"
"github.com/aws/aws-sdk-go-v2/service/sts"
)
func main() {
stsClient := sts.NewFromConfig(cfg)
// Create provider with MFA
provider := stscreds.NewAssumeRoleProvider(
stsClient,
"arn:aws:iam::ACCOUNT-ID:role/RoleName",
func(o *stscreds.AssumeRoleOptions) {
// Set MFA device serial number
o.SerialNumber = aws.String("arn:aws:iam::ACCOUNT-ID:mfa/username")
// Provide MFA token from stdin
o.TokenProvider = stscreds.StdinTokenProvider
},
)
credentials := aws.NewCredentialsCache(provider)
// Use credentials
}package main
import (
"github.com/aws/aws-sdk-go-v2/credentials/stscreds"
"github.com/aws/aws-sdk-go-v2/service/sts"
)
func getTokenFromCustomSource() (string, error) {
// Get MFA token from custom source (e.g., hardware token, app)
return "123456", nil
}
func main() {
stsClient := sts.NewFromConfig(cfg)
provider := stscreds.NewAssumeRoleProvider(
stsClient,
"arn:aws:iam::ACCOUNT-ID:role/RoleName",
func(o *stscreds.AssumeRoleOptions) {
o.SerialNumber = aws.String("arn:aws:iam::ACCOUNT-ID:mfa/username")
o.TokenProvider = getTokenFromCustomSource
},
)
credentials := aws.NewCredentialsCache(provider)
// Use credentials
}package main
import (
"github.com/aws/aws-sdk-go-v2/credentials/stscreds"
"github.com/aws/aws-sdk-go-v2/service/sts"
)
func main() {
stsClient := sts.NewFromConfig(cfg)
// Restrict role permissions with inline policy
restrictivePolicy := `{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket/*"
}
]
}`
provider := stscreds.NewAssumeRoleProvider(
stsClient,
"arn:aws:iam::ACCOUNT-ID:role/RoleName",
func(o *stscreds.AssumeRoleOptions) {
o.Policy = aws.String(restrictivePolicy)
},
)
credentials := aws.NewCredentialsCache(provider)
// Use credentials
}package main
import (
"github.com/aws/aws-sdk-go-v2/credentials/stscreds"
"github.com/aws/aws-sdk-go-v2/service/sts"
"github.com/aws/aws-sdk-go-v2/service/sts/types"
)
func main() {
stsClient := sts.NewFromConfig(cfg)
provider := stscreds.NewAssumeRoleProvider(
stsClient,
"arn:aws:iam::ACCOUNT-ID:role/RoleName",
func(o *stscreds.AssumeRoleOptions) {
// Add tags to the session
o.Tags = []types.Tag{
{
Key: aws.String("Department"),
Value: aws.String("Finance"),
},
{
Key: aws.String("Environment"),
Value: aws.String("Production"),
},
}
// Make tags transitive (apply to all sessions)
o.TransitiveTagKeys = []string{"Department"}
},
)
credentials := aws.NewCredentialsCache(provider)
// Use credentials
}package main
import (
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/credentials/stscreds"
"github.com/aws/aws-sdk-go-v2/service/sts"
)
func main() {
stsClient := sts.NewFromConfig(cfg)
// Create web identity token retriever from file
tokenFile := stscreds.IdentityTokenFile("/path/to/oidc/token")
// Create provider with web identity
provider := stscreds.NewWebIdentityRoleProvider(
stsClient,
"arn:aws:iam::ACCOUNT-ID:role/WebIdentityRole",
tokenFile,
)
credentials := aws.NewCredentialsCache(provider)
// Use credentials
}package main
import (
"github.com/aws/aws-sdk-go-v2/credentials/stscreds"
"github.com/aws/aws-sdk-go-v2/service/sts"
)
// Custom token retriever
type CustomTokenRetriever struct {
// Your fields
}
func (c *CustomTokenRetriever) GetIdentityToken() ([]byte, error) {
// Retrieve token from custom source
return []byte("eyJhbGc..."), nil
}
func main() {
stsClient := sts.NewFromConfig(cfg)
tokenRetriever := &CustomTokenRetriever{}
provider := stscreds.NewWebIdentityRoleProvider(
stsClient,
"arn:aws:iam::ACCOUNT-ID:role/WebIdentityRole",
tokenRetriever,
)
credentials := aws.NewCredentialsCache(provider)
// Use credentials
}const ProviderName = "AssumeRoleProvider"Name identifier for the AssumeRole credentials provider.
const WebIdentityProviderName = "WebIdentityCredentials"Name identifier for the web identity credentials provider.
var DefaultDuration = time.Duration(15) * time.MinuteDefault credential expiration duration for AssumeRoleProvider. Credentials will expire after 15 minutes if no custom duration is specified.
func StdinTokenProvider() (string, error)Prompts the user on stdout and reads an MFA token from stdin. Useful for interactive MFA scenarios.
Returns:
string: The MFA token read from standard inputerror: Error if reading from stdin failsBehavior:
Example:
provider := stscreds.NewAssumeRoleProvider(
stsClient,
roleARN,
func(o *stscreds.AssumeRoleOptions) {
o.SerialNumber = aws.String(mfaDevice)
o.TokenProvider = stscreds.StdinTokenProvider
},
)type AssumeRoleProvider struct {
// Has unexported fields
}Retrieves temporary credentials from STS by assuming an IAM role and tracks credential expiration.
Note: Not safe for concurrent use. Wrap with aws.CredentialsCache for concurrency safety and automatic credential caching.
func NewAssumeRoleProvider(client AssumeRoleAPIClient, roleARN string, optFns ...func(*AssumeRoleOptions)) *AssumeRoleProviderConstructs an AssumeRoleProvider that retrieves credentials by assuming an IAM role using STS.
Parameters:
client (AssumeRoleAPIClient): STS API client for AssumeRole operationsroleARN (string): ARN of the IAM role to assume (required)optFns (...func(*AssumeRoleOptions)): Functional options for configurationReturns:
*AssumeRoleProvider: Initialized credentials provider for assuming IAM rolesExample:
// Basic role assumption
provider := stscreds.NewAssumeRoleProvider(stsClient, roleARN)
// With options
provider := stscreds.NewAssumeRoleProvider(
stsClient,
roleARN,
func(o *stscreds.AssumeRoleOptions) {
o.RoleSessionName = "my-session"
o.Duration = 30 * time.Minute
},
)func (p *AssumeRoleProvider) Retrieve(ctx context.Context) (aws.Credentials, error)Generates a new set of temporary credentials by calling AssumeRole on the STS client.
Parameters:
ctx (context.Context): Context for the request, supports cancellation and timeoutsReturns:
aws.Credentials: New temporary credentials with expiration timeerror: Error if STS AssumeRole call failsExample:
creds, err := provider.Retrieve(context.TODO())
if err != nil {
log.Fatalf("Failed to retrieve credentials: %v", err)
}
fmt.Printf("Access Key: %s\n", creds.AccessKeyID)
fmt.Printf("Expires: %s\n", creds.Expires)func (p *AssumeRoleProvider) ProviderSources() []aws.CredentialSourceReturns the credential chain used to construct this provider.
Returns:
[]aws.CredentialSource: Credential source chain for debugging and reportingtype AssumeRoleAPIClient interface {
AssumeRole(ctx context.Context, params *sts.AssumeRoleInput, optFns ...func(*sts.Options)) (*sts.AssumeRoleOutput, error)
}Interface for an STS client capable of AssumeRole operations. Allows for custom implementations and mocking in tests.
Methods:
AssumeRole: Calls the STS AssumeRole operationtype AssumeRoleOptions struct {
Client AssumeRoleAPIClient
RoleARN string
RoleSessionName string
Duration time.Duration
ExternalID *string
Policy *string
PolicyARNs []types.PolicyDescriptorType
SerialNumber *string
SourceIdentity *string
TokenProvider func() (string, error)
Tags []types.Tag
TransitiveTagKeys []string
CredentialSources []aws.CredentialSource
}Configuration options for AssumeRoleProvider.
Fields:
Client (AssumeRoleAPIClient): Required. STS API client for AssumeRole operationsRoleARN (string): Required. ARN of the IAM role to assumeRoleSessionName (string): Session identifier for the assumed role. Used in AWS CloudTrail logs for trackingDuration (time.Duration): Credential expiration duration. If not set, defaults to 15 minutes. Must be between 15 minutes and 1 hour for most rolesExternalID (*string): Optional external ID required to assume the role. Use when the role has an external ID conditionPolicy (*string): Optional inline session policy document (plain text JSON). Maximum size is 2048 bytes. Restricts permissions to intersection of role policy and session policyPolicyARNs ([]types.PolicyDescriptorType): Optional managed policy ARNs to attach to the session. Maximum 10 policiesSerialNumber (*string): MFA device serial number or ARN (e.g., "arn:aws:iam::ACCOUNT-ID:mfa/username"). Required if MFA is neededSourceIdentity (*string): Optional source identity for CloudTrail logging and cross-account access trackingTokenProvider (func() (string, error)): Optional MFA token provider function. Called when MFA is required. Use StdinTokenProvider for interactive inputTags ([]types.Tag): Optional session tags for tracking and audit. Maximum 50 tagsTransitiveTagKeys ([]string): Optional keys that should be transitive (apply to all chained sessions)CredentialSources ([]aws.CredentialSource): Credential chain information for reporting (not meant to be set directly)Example:
options := stscreds.AssumeRoleOptions{
Client: stsClient,
RoleARN: "arn:aws:iam::ACCOUNT-ID:role/RoleName",
RoleSessionName: "my-app-session",
Duration: 30 * time.Minute,
SerialNumber: aws.String("arn:aws:iam::ACCOUNT-ID:mfa/user"),
TokenProvider: stscreds.StdinTokenProvider,
}type WebIdentityRoleProvider struct {
// Has unexported fields
}Retrieves temporary credentials using an OIDC/web identity token. Useful for federated identity scenarios where applications authenticate via external identity providers.
Note: Not safe for concurrent use. Wrap with aws.CredentialsCache for concurrency safety and automatic credential caching.
func NewWebIdentityRoleProvider(client AssumeRoleWithWebIdentityAPIClient, roleARN string, tokenRetriever IdentityTokenRetriever, optFns ...func(*WebIdentityRoleOptions)) *WebIdentityRoleProviderConstructs a WebIdentityRoleProvider with provided configuration.
Parameters:
client (AssumeRoleWithWebIdentityAPIClient): STS API client for AssumeRoleWithWebIdentity operationsroleARN (string): ARN of the IAM role to assume (required)tokenRetriever (IdentityTokenRetriever): JWT token retriever implementation (required)optFns (...func(*WebIdentityRoleOptions)): Functional options for configurationReturns:
*WebIdentityRoleProvider: Initialized web identity credentials providerExample:
tokenFile := stscreds.IdentityTokenFile("/path/to/token")
provider := stscreds.NewWebIdentityRoleProvider(
stsClient,
"arn:aws:iam::ACCOUNT-ID:role/WebRole",
tokenFile,
)func (p *WebIdentityRoleProvider) Retrieve(ctx context.Context) (aws.Credentials, error)Attempts to assume role using the web identity token and returns temporary credentials.
Parameters:
ctx (context.Context): Context for the request, supports cancellation and timeoutsReturns:
aws.Credentials: Retrieved temporary credentialserror: Error if token file not found, expired, malformed, or if STS call failsErrors:
Example:
creds, err := provider.Retrieve(context.TODO())
if err != nil {
log.Fatalf("Failed to retrieve credentials: %v", err)
}
fmt.Printf("Access Key: %s\n", creds.AccessKeyID)func (p *WebIdentityRoleProvider) ProviderSources() []aws.CredentialSourceReturns the credential chain used to construct this provider.
Returns:
[]aws.CredentialSource: Credential source chain for debugging and reportingtype AssumeRoleWithWebIdentityAPIClient interface {
AssumeRoleWithWebIdentity(ctx context.Context, params *sts.AssumeRoleWithWebIdentityInput, optFns ...func(*sts.Options)) (*sts.AssumeRoleWithWebIdentityOutput, error)
}Interface for an STS client capable of AssumeRoleWithWebIdentity operations. Allows custom implementations and mocking.
Methods:
AssumeRoleWithWebIdentity: Calls the STS AssumeRoleWithWebIdentity operationtype IdentityTokenFile stringString type implementing IdentityTokenRetriever interface for retrieving JWT tokens from a file.
func (j IdentityTokenFile) GetIdentityToken() ([]byte, error)Retrieves JWT token from the file and returns contents as bytes.
Returns:
[]byte: JWT token file contentserror: Error if file cannot be readExample:
// Read token from file
tokenFile := stscreds.IdentityTokenFile("/var/run/secrets/oidc-token")
token, err := tokenFile.GetIdentityToken()
if err != nil {
log.Fatalf("Failed to read token: %v", err)
}
fmt.Printf("Token length: %d bytes\n", len(token))type IdentityTokenRetriever interface {
GetIdentityToken() ([]byte, error)
}Interface for retrieving a JWT identity token. Implement this interface for custom token loading logic.
Methods:
GetIdentityToken() ([]byte, error): Returns the JWT token as bytesExample Implementation:
// Custom retriever that fetches from HTTP endpoint
type HTTPTokenRetriever struct {
URL string
}
func (h *HTTPTokenRetriever) GetIdentityToken() ([]byte, error) {
resp, err := http.Get(h.URL)
if err != nil {
return nil, err
}
defer resp.Body.Close()
return io.ReadAll(resp.Body)
}
// Use in provider
retriever := &HTTPTokenRetriever{URL: "http://localhost:8080/token"}
provider := stscreds.NewWebIdentityRoleProvider(
stsClient,
roleARN,
retriever,
)type WebIdentityRoleOptions struct {
Client AssumeRoleWithWebIdentityAPIClient
TokenRetriever IdentityTokenRetriever
RoleARN string
RoleSessionName string
Duration time.Duration
Policy *string
PolicyARNs []types.PolicyDescriptorType
CredentialSources []aws.CredentialSource
}Configuration options for WebIdentityRoleProvider.
Fields:
Client (AssumeRoleWithWebIdentityAPIClient): Required. STS API client for web identity operationsTokenRetriever (IdentityTokenRetriever): Required. JWT token provider implementationRoleARN (string): Required. ARN of the IAM role to assumeRoleSessionName (string): Optional session identifier. Used in CloudTrail logs and for trackingDuration (time.Duration): Optional credential expiration duration. If not set, STS assigns a default (typically 1 hour). Maximum 12 hoursPolicy (*string): Optional inline session policy document in JSON formatPolicyARNs ([]types.PolicyDescriptorType): Optional managed policy ARNs to attach to the sessionCredentialSources ([]aws.CredentialSource): Credential chain information for reporting (not meant to be set directly)Example:
options := stscreds.WebIdentityRoleOptions{
Client: stsClient,
TokenRetriever: tokenFile,
RoleARN: "arn:aws:iam::ACCOUNT-ID:role/WebRole",
RoleSessionName: "my-app",
Duration: 1 * time.Hour,
}Common error scenarios when using stscreds:
Example:
creds, err := provider.Retrieve(ctx)
if err != nil {
if strings.Contains(err.Error(), "not authorized to perform") {
log.Fatal("Caller lacks permissions to assume role")
}
if strings.Contains(err.Error(), "MFA Authentication failed") {
log.Fatal("Invalid MFA token provided")
}
log.Fatalf("Failed to assume role: %v", err)
}Example:
creds, err := provider.Retrieve(ctx)
if err != nil {
if strings.Contains(err.Error(), "no such file or directory") {
log.Fatal("Identity token file not found")
}
if strings.Contains(err.Error(), "invalid token") {
log.Fatal("Token is expired or malformed")
}
log.Fatalf("Failed to retrieve web identity credentials: %v", err)
}When MFA is required, provide both the MFA device serial number and a token provider:
provider := stscreds.NewAssumeRoleProvider(
stsClient,
roleARN,
func(o *stscreds.AssumeRoleOptions) {
// Set MFA device ARN
o.SerialNumber = aws.String("arn:aws:iam::ACCOUNT-ID:mfa/username")
// Provide token source
o.TokenProvider = stscreds.StdinTokenProvider
},
)// Token provider that reads from environment variable
func getTokenFromEnv() (string, error) {
token := os.Getenv("AWS_MFA_TOKEN")
if token == "" {
return "", fmt.Errorf("AWS_MFA_TOKEN environment variable not set")
}
return token, nil
}
provider := stscreds.NewAssumeRoleProvider(
stsClient,
roleARN,
func(o *stscreds.AssumeRoleOptions) {
o.SerialNumber = aws.String(mfaDevice)
o.TokenProvider = getTokenFromEnv
},
)Always wrap with CredentialsCache: The provider is not thread-safe and doesn't cache credentials internally
provider := stscreds.NewAssumeRoleProvider(stsClient, roleARN)
creds := aws.NewCredentialsCache(provider)Use session names for tracking: Include meaningful session names for CloudTrail logging and debugging
func(o *stscreds.AssumeRoleOptions) {
o.RoleSessionName = "app-prod-session"
}Set appropriate duration: Choose duration that balances security and operational overhead
func(o *stscreds.AssumeRoleOptions) {
o.Duration = 30 * time.Minute // 15 min - 1 hour
}Use session policies for least privilege: Restrict assumed role permissions with inline policies
func(o *stscreds.AssumeRoleOptions) {
o.Policy = aws.String(restrictivePolicy)
}Add tags for audit trail: Use session tags for tracking and compliance
func(o *stscreds.AssumeRoleOptions) {
o.Tags = []types.Tag{
{Key: aws.String("Application"), Value: aws.String("MyApp")},
}
}Handle MFA securely: Don't hardcode MFA tokens; use secure token providers
// Good: Use dynamic provider
o.TokenProvider = stscreds.StdinTokenProvider
// Avoid: Hardcoding tokens
o.TokenProvider = func() (string, error) {
return "123456", nil
}Set context timeouts: Use appropriate context timeouts for STS calls
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
creds, err := provider.Retrieve(ctx)Verify role trust relationships: Ensure roles are properly configured for assumption
// Role trust policy must include:
{
"Principal": {
"AWS": "arn:aws:iam::SOURCE-ACCOUNT:role/SourceRole"
},
"Effect": "Allow",
"Action": "sts:AssumeRole"
}Use external IDs for cross-account access: When assuming roles in other accounts, use external IDs for additional security
func(o *stscreds.AssumeRoleOptions) {
o.ExternalID = aws.String("unique-external-id")
}Monitor credential refresh: CredentialsCache handles refresh automatically, but monitor for refresh failures
// CredentialsCache will refresh before expiration
// Failures are handled by extending expiration if possibleimport (
"context"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/s3"
)
func main() {
// Load default config
cfg, err := config.LoadDefaultConfig(context.TODO())
if err != nil {
panic(err)
}
// Create service client - will use default credential chain
client := s3.NewFromConfig(cfg)
// Use client
}