Diridp is an OpenID Connect identity provider that issues tokens (JWTs) as regular files on the local filesystem.
The tokens generated by diridp are typically used by other processes on the same machine to identify themselves to some third party service. Because diridp rotates all signing keys and tokens, these can replace otherwise permanent credentials that would be used instead.
A minimal config looks like:
yaml
providers:
main:
issuer: "https://example.com"
tokens:
- path: "/run/diridp/my-application/token"
claims:
sub: "my-application"
aud: "some-cloud-service.example.com"
See the configuration template for all available options.
Diridp is built to require no network access at all. Serving the OpenID Connect
documents is left to an external process like Nginx or Apache httpd. Typically,
you'd configure an HTTPS virtual host to serve from
/var/lib/diridp/<provider>/webroot
. In Nginx, this may look like:
```nginx server { listen 0.0.0.0:443 ssl; servername example.com; sslcertificate /etc/nginx/ssl/example.com/fullchain.pem; sslcertificatekey /etc/nginx/ssl/example.com/privkey.pem;
# All files in this root are JSON, but may not have the extension. root /var/lib/diridp/main/webroot; types { } default_type application/json; } ```
If you'd like to serve other content from the same vhost, you may also configure locations for the two specific files that need to be served:
```nginx location = /.well-known/openid-configuration { root /var/lib/diridp/main/webroot; types { } default_type application/json; }
jwks_path
option in diridp config.location = /jwks.json { root /var/lib/diridp/main/webroot; types { } default_type application/json; } ```
An identity provider can be created in AWS IAM. This instructs AWS how to verify tokens. In Terraform syntax, this'd look like:
```hcl locals { exampleidphost = "example.com" }
resource "awsiamopenidconnectprovider" "exampleidp" {
# This must match the issuer
setting in diridp, and virtual host.
url = "https://${local.exampleidp_host}"
# This must match the aud
claim in the diridp token.
clientidlist = ["sts.amazonaws.com"]
# This pins the certificate authority (CA) that issued the HTTPS certificate,
# and is required by AWS. Here we determine it at terraform apply
time, so
# if the CA certificate ever changes, simply re-apply the Terraform config.
# This requires the hashicorp/tls
provider.
thumbprintlist = [data.tlscertificate.exampleidp.certificates[0].sha1fingerprint]
}
data "tlscertificate" "exampleidp" { url = "https://${local.exampleidphost}" } ```
Once configured, AWS will accept tokens from this identity provider in calls to
the STS AssumeRoleWithWebIdentity
action, but we first need to create a role
that can be assumed with the token:
```hcl resource "awsiamrole" "examplerole" { name = "examplerole"
assumerolepolicy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = "sts:AssumeRoleWithWebIdentity"
Principal = {
Federated = awsiamopenidconnectprovider.exampleidp.arn
}
Condition = {
# This limits the role to tokens with a matching sub
claim.
StringLike = {
"${local.exampleidp_host}:sub" = "my-application"
}
}
}
]
})
}
```
(The above example role has no permissions at all. You'd typically attach some policies to it to allow it to actually do anything.)
Now, you can use the role in any application using the offical AWS SDKs by setting these environment variables:
```bash
path
in diridp configuration.AWSWEBIDENTITYTOKENFILE="/run/diridp/my-application/token"
AWSROLEARN="arn:aws:iam::123456789:role/example_role" ```
Behind the scenes, the AWS SDK does something similar to the following AWS CLI command:
bash
aws sts assume-role-with-web-identity \
--role-arn "arn:aws:iam::123456789:role/example_role" \
--role-session-name "<generated by the SDK>" \
--web-identity-token "<token contents>"
This effectively creates a regular AWS access key with a very short lifetime (1 hour by default) and then continues as normal using that access key. But the AWS SDK handles automatic refresh for you.
By using a path with a parameter, new tokens can be defined at run-time simply by creating directories:
yaml
providers:
main:
issuer: "https://example.com"
tokens:
- path: "/run/diridp/containers/:sub/aws_token"
claims:
aud: "sts.amazonaws.com"
Docker automatically creates directories for volume mounts, so an application using the AWS SDK could be started as follows:
bash
docker run \
-v /run/diridp/containers/my_app:/run/secrets/diridp:ro \
-e AWS_WEB_IDENTITY_TOKEN_FILE=/run/secrets/diridp/aws_token \
-e AWS_ROLE_ARN=arn:aws:iam::123456789:role/example_role \
my_app:latest
Note that when stopping / removing containers, these directories are not automatically cleaned up.