denoland / deploy_feedback

For reporting issues with Deno Deploy
https://deno.com/deploy
74 stars 5 forks source link

Consider issuing OIDC tokens, for hardened AWS/Google/etc access #150

Open danopia opened 2 years ago

danopia commented 2 years ago

OpenID Connect (OIDC) is a technology that's getting adopted by numerous cloud providers for machine-to-machine, cloud-to-cloud authentication. OIDC support would allow a Deno Deploy program to access AWS resources such as DynamoDB without the app having any 'secrets' configured at all!

How the flow works

A JWT can be issued by the provider (e.g. Deno Deploy) for an arbitrary audience (e.g. AWS) and given to the deployment on request. The deployment can then send its new JWT in a request to the other service. Usually the JWT is used to get a new token from that third-party platform which expires after maybe 1 hour.

Because the provider platform issues the JWT, it contains strong assertions about the 'subject' of the token, such as a repository name or a deployment ID. The third-party platform can then be configured to check the token's issuer and subject to determine whether to allow the access. So in AWS you could create an IAM role that can only be assumed by a particular Deno Deploy deployment ID, if deployment ID is in Deno Deploy's JWT.

What is involved

Who implements this already

JWT audiences

These are services I know of that could immediately work with Deno Deploy tokens if it introduced them today.

JWT issuers

These are providers that have prior art on giving tokens to running code. * Kubernetes can issue OIDC JWTs to pods. These are issued by the cluster itself and include Namespace, Pod, and ServiceAccount info. They are stored in temporary files and get rotated every hour by default. The pod's configuration includes token requests, so they are available as soon as the pod is started. * [Sample openid-configuration](https://danopia.net/kubernetes-identity/.well-known/openid-configuration) from my own cluster. * Amazon enables this by default for [their 'IRSA' solution](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html), which is used with a pod config like so: ```yaml containers: - ..... env: - name: AWS_REGION value: us-west-2 - name: AWS_ROLE_ARN value: "arn:aws:iam::111122223333:role/s3-reader" - name: AWS_WEB_IDENTITY_TOKEN_FILE # The AWS SDK watches this file value: "/var/run/secrets/eks.amazonaws.com/serviceaccount/token" volumeMounts: - mountPath: "/var/run/secrets/eks.amazonaws.com/serviceaccount/" name: aws-token volumes: - name: aws-token projected: sources: - serviceAccountToken: audience: "sts.amazonaws.com" expirationSeconds: 86400 # AWS configures a longer 24-hour expiration path: token ``` The AWS SDKs automatically find and use these tokens, so the user's code does not need any adjustments to work. * Google GKE enables this if the cluster has [Workload Identity](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity) toggled to on. * [Sample openid-configuration](https://container.googleapis.com/v1/projects/stardust-156404/locations/us-central1-f/clusters/dust/.well-known/openid-configuration) * Github Actions now has [an API endpoint that can issue JWTs](https://github.blog/changelog/2021-10-27-github-actions-secure-cloud-deployments-with-openid-connect/). The workload is given environment variables that point to an issuing URL, including a random secret. The tokens contain verbose details like trigger type, branch, githash, relevant user, and workflow ID. * [Documentation for integrating with multiple cloud providers](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments). * [openid-configuration for issuer `https://token.actions.githubusercontent.com`)](https://token.actions.githubusercontent.com/.well-known/openid-configuration) * Gitlab CI issues a default token `$CI_JOB_JWT_V2` as of 14.6. * [Documentation for integrating for AWS access](https://docs.gitlab.com/ee/ci/cloud_services/aws/). * [The audience is not configurable](https://docs.gitlab.com/ee/ci/variables/predefined_variables.html) and they document that this can cause multi-party trust issues. * [openid-configuration for issuer `https://gitlab.com`](https://gitlab.com/.well-known/openid-configuration) * CircleCI similarly has a `$CIRCLE_OIDC_TOKEN` environment variable, [docs here](https://circleci.com/docs/2.0/openid-connect-tokens/). They're creating an issuer/JWKS per organization instead of one central signing key for everybody. Also all kinds of OAuth sign-in providers are OIDC-compliant, like Google Accounts, Cloudflare Access, Auth0, Keycloak, ....

Downsides

For those reasons, JWTs won't entirely replace static credentials, especially for users just getting started. However it is an excellent tool for hardened access and provides stronger API trust with less credential upkeep.

MiguelRipoll23 commented 2 years ago

Huge fan of Workload Identity Federation, it feels like OATH2 for CI/CD. I would love to see this as a new user using Deno Deploy.