mirror of
https://github.com/open-policy-agent/opa.git
synced 2026-08-12 19:32:48 -06:00
Support reading AWS token from the filesystem
Signed-off-by: Curtis Maddalozzo <cmaddalozzo@bloomberg.net>
This commit is contained in:
committed by
GitHub
parent
d250ea485e
commit
cdd09e5966
+21
-7
@@ -30,10 +30,11 @@ const (
|
||||
ec2DefaultTokenPath = "http://169.254.169.254/latest/api/token"
|
||||
|
||||
// ref. https://docs.aws.amazon.com/AmazonECS/latest/userguide/task-iam-roles.html
|
||||
ecsDefaultCredServicePath = "http://169.254.170.2"
|
||||
ecsRelativePathEnvVar = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"
|
||||
ecsFullPathEnvVar = "AWS_CONTAINER_CREDENTIALS_FULL_URI"
|
||||
ecsAuthorizationTokenEnvVar = "AWS_CONTAINER_AUTHORIZATION_TOKEN"
|
||||
ecsDefaultCredServicePath = "http://169.254.170.2"
|
||||
ecsRelativePathEnvVar = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"
|
||||
ecsFullPathEnvVar = "AWS_CONTAINER_CREDENTIALS_FULL_URI"
|
||||
ecsAuthorizationTokenEnvVar = "AWS_CONTAINER_AUTHORIZATION_TOKEN"
|
||||
ecsAuthorizationTokenFileEnvVar = "AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE"
|
||||
|
||||
// ref. https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html
|
||||
stsDefaultDomain = "amazonaws.com"
|
||||
@@ -277,9 +278,22 @@ func (cs *awsMetadataCredentialService) refreshFromService(ctx context.Context)
|
||||
// if using the AWS_CONTAINER_CREDENTIALS_FULL_URI variable, we need to associate the token
|
||||
// to the request
|
||||
if _, useFullPath := os.LookupEnv(ecsFullPathEnvVar); useFullPath {
|
||||
token, tokenExists := os.LookupEnv(ecsAuthorizationTokenEnvVar)
|
||||
if !tokenExists {
|
||||
return errors.New("unable to get ECS metadata authorization token")
|
||||
var token string
|
||||
tokenFilePath, tokenFilePathExists := os.LookupEnv(ecsAuthorizationTokenFileEnvVar)
|
||||
|
||||
if tokenFilePathExists {
|
||||
tokenBytes, err := os.ReadFile(tokenFilePath)
|
||||
if err != nil {
|
||||
return errors.New("failed to read ECS metadata authorization token from file: " + err.Error())
|
||||
}
|
||||
token = string(tokenBytes)
|
||||
// If token doesn't exist as a file check if it exists as an environment variable
|
||||
} else {
|
||||
var tokenExists bool
|
||||
token, tokenExists = os.LookupEnv(ecsAuthorizationTokenEnvVar)
|
||||
if !tokenExists {
|
||||
return errors.New("unable to get ECS metadata authorization token")
|
||||
}
|
||||
}
|
||||
req.Header.Set("Authorization", token)
|
||||
}
|
||||
|
||||
@@ -358,6 +358,16 @@ func TestMetadataCredentialService(t *testing.T) {
|
||||
assertErr("unable to get ECS metadata authorization token", err, t)
|
||||
os.Unsetenv(ecsFullPathEnvVar)
|
||||
|
||||
test.WithTempFS(nil, func(path string) {
|
||||
// wrong path: bad file token
|
||||
t.Setenv(ecsFullPathEnvVar, "fullPath")
|
||||
os.Setenv(ecsAuthorizationTokenFileEnvVar, filepath.Join(path, "bad-file"))
|
||||
_, err = cs.credentials(context.Background())
|
||||
assertErr("failed to read ECS metadata authorization token from file", err, t)
|
||||
os.Unsetenv(ecsFullPathEnvVar)
|
||||
os.Unsetenv(ecsAuthorizationTokenFileEnvVar)
|
||||
})
|
||||
|
||||
// wrong path: creds not found
|
||||
cs = awsMetadataCredentialService{
|
||||
RoleName: "not_my_iam_role", // not present
|
||||
@@ -525,6 +535,39 @@ func TestMetadataCredentialService(t *testing.T) {
|
||||
assertEq(creds.SessionToken, ts.payload.Token, t)
|
||||
os.Unsetenv(ecsFullPathEnvVar)
|
||||
os.Unsetenv(ecsAuthorizationTokenEnvVar)
|
||||
|
||||
// happy path: credentials fetched from full path var using token from filesystem
|
||||
files := map[string]string{
|
||||
"good_token_file": "THIS_IS_A_GOOD_TOKEN",
|
||||
}
|
||||
test.WithTempFS(files, func(path string) {
|
||||
// happy path: credentials fetched from full path var
|
||||
cs = awsMetadataCredentialService{
|
||||
RegionName: "us-east-1",
|
||||
credServicePath: "", // not set as we want to test env var resolution
|
||||
logger: logging.Get(),
|
||||
}
|
||||
ts.payload = metadataPayload{
|
||||
AccessKeyID: "MYAWSACCESSKEYGOESHERE",
|
||||
SecretAccessKey: "MYAWSSECRETACCESSKEYGOESHERE",
|
||||
Code: "Success",
|
||||
Token: "MYAWSSECURITYTOKENGOESHERE",
|
||||
Expiration: time.Now().UTC().Add(time.Minute * 2)} // short time
|
||||
t.Setenv(ecsFullPathEnvVar, ts.server.URL+"/fullPath")
|
||||
t.Setenv(ecsAuthorizationTokenFileEnvVar, filepath.Join(path, "good_token_file"))
|
||||
creds, err = cs.credentials(context.Background())
|
||||
if err != nil {
|
||||
// Cannot proceed with test if unable to fetch credentials.
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assertEq(creds.AccessKey, ts.payload.AccessKeyID, t)
|
||||
assertEq(creds.SecretKey, ts.payload.SecretAccessKey, t)
|
||||
assertEq(creds.RegionName, cs.RegionName, t)
|
||||
assertEq(creds.SessionToken, ts.payload.Token, t)
|
||||
os.Unsetenv(ecsFullPathEnvVar)
|
||||
os.Unsetenv(ecsAuthorizationTokenFileEnvVar)
|
||||
})
|
||||
}
|
||||
|
||||
func TestMetadataServiceErrorHandled(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user