Based on an exiting AWS context demonstrate hwo to construct a JWT in order to terraform Entra ID.
This removes the burden of manually rotating secrets in order to access Entra ID on a regular basis. Still, rotation happens, but instead of using Client Secret or Certificates (having expiry dates) provide a reference to a public key for validation. As the reference is backed by AWS, it becomes easier to implement rotation.
To run this from scratch:
Install some tools
brew install jq jwt-cli terraform
Provide an .env
file and source it, e.g. using export $(grep -v '^#' .env | xargs)
.
AWS_PROFILE=<MY_PROFILE>
ARM_TENANT_ID=<MY_TENANT_ID>
ARM_CLIENT_ID=<MY_APP_REGISTRATION_ID_AKA_CLIENT_ID>
Requires AWS access and will generate assets required to configure Azure initally.
aws sso login
pushd ./prereqs
terraform init && terraform apply
popd
It will prepare
- the key pair required to sign and validate tokens
- convert the RSA key into a JWKS
- publish the JWKS using S3 and CloudFront (could be any other publicy accessible URL)
- output values enabling subsequent operations, i.e. token creation
To inspect the sensitive output you may use terraform output -json
.
Grab value of entra.iss
and entra.sub
from previous terraform's output and configure it as a federated credential in AppRegistration.
The token contains a subject which is known to Entra ID and a public key (via Distribution URL) to ensure the JWT is signed by to owner of the correspinding private key.
Ensure, that the AppRegistration is owned by its corresponding Enterprise Application (aka. Service Principal).
It might be required to use the CLI to accomplish this.
Option --owner-object-id
accepts the Enterprise Application's GUID.
Finally, terraform Azure using a JWT.
./demo.sh
The terraform-entra
part performs read operations, only.
It outputs users owning the AppRegistration used for authentication.
As the JWK is valid for three days you may use ./demo.sh skip-prereqs
directly.
The azread
provider is configured using the Service Principal with OIDC capability.
Option ARM_OIDC_TOKEN
is set to the token created before.
For token validation you may issue ./demo.sh skip-prereqs token-only
.
It outputs values required for the validation.
- Post the token (output
jwt
) - Enter the distribution URL for JWKS (output
jwks_url
)
Expect the token to be verified.
This is just a domonstrator and real world usage will differ.
- Revisit the public CloudFront endpoint
- Handle the private key outside terraform state
- Publish two versions having different expiries of JWK in parallel
- Revisit values of token's
iss
andsub
fields