You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Vault AWS STS角色假设:POST生成凭证及续期方案咨询

Great question! I've tackled this exact scenario before, so let's walk through the best ways to handle generating AWS STS credentials via Vault's aws/sts backend (which requires a POST request) and managing their renewal—since @VaultPropertySource only supports GET operations, we need to build a custom flow.

Option 1: Use VaultTemplate to Manually Generate & Retrieve Credentials

Spring Cloud Vault provides VaultTemplate, which lets you send arbitrary HTTP requests to Vault. This is perfect for triggering the POST request to generate STS credentials, then extracting the resulting temp credentials.

Step 1: Define a Credential POJO

First, create a simple class to hold the STS credentials from Vault:

public record AwsStsCredentials(
    String accessKey,
    String secretKey,
    String securityToken,
    Duration ttl
) {}

Step 2: Write a Method to Generate Credentials

Inject VaultTemplate into your service/config class, then implement a method to send the POST request:

import org.springframework.vault.core.VaultTemplate;
import org.springframework.vault.core.VaultResponse;

@Service
public class VaultStsService {

    private final VaultTemplate vaultTemplate;

    public VaultStsService(VaultTemplate vaultTemplate) {
        this.vaultTemplate = vaultTemplate;
    }

    public AwsStsCredentials generateStsCredentials(String roleName) {
        // Build the POST request body (adjust role ARN/TTL to match your setup)
        var request = Map.of(
            "role_arn", "arn:aws:iam::123456789012:role/your-vault-linked-role",
            "ttl", "1h"
        );

        // Send POST to Vault's aws/sts endpoint
        VaultResponse response = vaultTemplate.write("aws/sts/" + roleName, request);
        if (response == null || response.getData() == null) {
            throw new IllegalStateException("Failed to fetch STS credentials from Vault");
        }

        // Parse the response into our POJO
        var credData = (Map<String, Object>) response.getData().get(roleName);
        return new AwsStsCredentials(
            (String) credData.get("access_key"),
            (String) credData.get("secret_key"),
            (String) credData.get("security_token"),
            Duration.parse((String) credData.get("ttl"))
        );
    }
}

Option 2: Integrate with AWS SDK's Credential Provider (Automatic Renewal)

For a more seamless integration with AWS services, wrap the credential generation logic into an AWSCredentialsProvider. This lets the AWS SDK automatically fetch/refresh credentials when needed.

Implement the Custom Credential Provider

import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSCredentialsProvider;
import com.amazonaws.auth.BasicSessionCredentials;
import org.springframework.stereotype.Component;

import java.time.Instant;

@Component
public class VaultStsCredentialsProvider implements AWSCredentialsProvider {

    private final VaultStsService vaultStsService;
    private AwsStsCredentials currentCredentials;
    private Instant nextRenewalTime;

    public VaultStsCredentialsProvider(VaultStsService vaultStsService) {
        this.vaultStsService = vaultStsService;
        // Initialize credentials on startup
        renewCredentials();
    }

    @Override
    public AWSCredentials getCredentials() {
        // Renew credentials if we're within 5 minutes of expiration
        if (Instant.now().isAfter(nextRenewalTime.minusMinutes(5))) {
            renewCredentials();
        }
        return new BasicSessionCredentials(
            currentCredentials.accessKey(),
            currentCredentials.secretKey(),
            currentCredentials.securityToken()
        );
    }

    private void renewCredentials() {
        this.currentCredentials = vaultStsService.generateStsCredentials("your-role-name");
        // Set next renewal time to 5 minutes before the credential expires
        this.nextRenewalTime = Instant.now().plus(currentCredentials.ttl()).minusMinutes(5);
    }

    @Override
    public void refresh() {
        renewCredentials();
    }
}

Use the Provider with AWS SDK

Now you can inject this provider into your AWS client builders:

import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AwsConfig {

    @Bean
    public AmazonS3 amazonS3(VaultStsCredentialsProvider credentialsProvider) {
        return AmazonS3ClientBuilder.standard()
            .withCredentials(credentialsProvider)
            .withRegion("us-east-1")
            .build();
    }
}

Option 3: Scheduled Credential Renewal (For Non-AWS SDK Use Cases)

If you need credentials for non-AWS SDK operations, use Spring's scheduled tasks to refresh credentials periodically and store them in a cache.

Example with Spring Cache

import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class VaultStsCredentialRefresher {

    private final VaultStsService vaultStsService;
    private final Cache credentialCache;

    public VaultStsCredentialRefresher(VaultStsService vaultStsService, CacheManager cacheManager) {
        this.vaultStsService = vaultStsService;
        this.credentialCache = cacheManager.getCache("aws-sts-credentials");
        // Initialize cache on startup
        refreshCredentials();
    }

    // Renew every 55 minutes (matches 1h TTL minus 5 minutes buffer)
    @Scheduled(fixedRate = 3300000)
    public void refreshCredentials() {
        var credentials = vaultStsService.generateStsCredentials("your-role-name");
        credentialCache.put("default-role", credentials);
    }
}

Access Credentials from Cache

@Autowired
private Cache credentialCache;

public void runCustomAwsOperation() {
    AwsStsCredentials credentials = credentialCache.get("default-role", () -> 
        vaultStsService.generateStsCredentials("your-role-name")
    );
    // Use credentials for your operation
}

Key Considerations

  • Vault Policy Permissions: Ensure your Vault token has create (for POST) and read permissions on the aws/sts/* path:
    path "aws/sts/your-role-name" {
      capabilities = ["create", "read"]
    }
    
  • Error Handling: Add retry logic (using Spring Retry) for Vault connection failures or credential generation errors to avoid downtime.
  • Security: Keep your Vault token's TTL aligned with your STS credential TTL, and ensure the token has minimal necessary permissions.

内容的提问来源于stack exchange,提问作者Darrell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:16:18