AWS IAM Auth with PowerShell (or really anything friendly that doesn't just return a blob of text)

Hello. I’m able to use vault.exe login with the AWS IAM method but trying to find a better solution. Looking for some suggestions other than relying on the helper (though maybe that is the answer, if so let me know - I have a series of Powershell commands for interacting with Vault already that I would prefer to use rather than vault.exe, if possible)

The simple answer is to use vault.exe, however, when you call the auth method of vault.exe, it doesn’t return anything friendly in Windows, it returns a blob of text, which happens to have a hashtable embedded in it…

C:\Windows\system32> $vault = & "$vaultPath\\vault.exe" login -method=aws role=base
C:\Windows\system32>$vault
Success! You are now authenticated. The token information displayed below
is already stored in the token helper. You do NOT need to run "vault login"
again. Future Vault requests will automatically use this token.

Key                      Value
---                      -----
token                    .4444444444444444444444uVM
token_accessor           hj44444444444444444444444444
token_duration           24h
token_renewable          true
token_policies           ["yaml:base"]
identity_policies        []
policies                 ["yaml:base"]
token_meta_account_id    123445
token_meta_auth_type     iam
token_meta_role_id       4444444444444444444444

This is borderline useless. Sure I can do something like $vault[6] to get the token line, than parse that to find the actual token, but what a hassle. When I use LDAP login using Invoke-RestMethod, it’s very simple, you auth, and you get back an object, or Invoke-WebRequest returns content that is very easily parsed into an object, things are simple.

AWS IAM Auth, not so much. I’ve been searching the last 3 hours and information is scarce at best.

The hashicorp documentation makes it sound so simple, just attach a base64 encoded EC2 Identity document and a base64 encoded SHA256 signature, and viola, only it’s not that simple…

# Get the json identity document and encode it
$resp = Invoke-WebRequest 'http://169.254.169.254/latest/dynamic/instance-identity/document'
$base64IdDoc = [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($resp.content))

# Build a SHA256 string and encode it
$str = "-----BEGIN RSA2048-----`n"
$str += Invoke-RestMethod 'http://169.254.169.254/latest/dynamic/instance-identity/rsa2048'
$str += "`n-----END RSA2048-----"
$base64Sha = [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($str))

$payload = @{
    'identity' = $base64IdDoc;
    'signature' = $base64Sha;
    'role' = 'base';
    'region'='us-west-2'
}

Invoke-WebRequest -Uri 'https://vaulturl/v1/auth/aws/login' -Method POST -Body ($pay | ConvertTo-Json)

But this fails and results in the error:

Invoke-WebRequest : {"errors":["instance identity verification using SHA256 RSA signature is unsuccessful"]}
At line:24 char:6

so I’ve been doing more digging, and it seems likely I need to access AWS STS to get my GetCallerIdentity and do something with it, but this is where things really start to fall apart and get muddy and unclear with pretty poor documentation.

Honestly I’d settle for vault.exe -json or something at this point, but such a thing doesn’t seem to exist.

Looking for some direction, thanks.

There’s a -format=json option you could use.

The placement of the option is somewhat particular, I believe this will get what you’re after:
vault login -format=json -method=aws role=base

I’d have to do a bit more digging for API only login instructions, however.

Thanks, the -format=json worked out just fine, would be nice to have something 100% native API but I’m not sure it’s worth the effort at this point