AWS Custom Node.js OIDC Provider Server on Heroku

2 min read aws, nodejs, heroku, iam, oidc

example of a custom nodejs OIDC provider server running on heroku for use as a custom AWS OIDC identity provider.

Demo Overview

  1. User logs into a web app with any username and password
  2. It returns an id_token (JWT) in the URL
  3. The id_token is used in the AWS STS assume-role-with-web-identity call to get temporary credentials which can be used to access AWS services

Deploy OIDC Server to Heroku

  1. If git not initialized, init it

    git init
    
  2. Create a heroku app

    heroku create --addons securekey,heroku-redis:hobby-dev
    

  3. Enable (experimental) runtime-dyno-metadata

    heroku labs:enable runtime-dyno-metadata
    

  4. Commit to your local repo

    git add .
    git commit -a -m 'my initial commit'
    
  5. Deploy to heroku

    git push heroku master
    
  6. see your openid-configuration

    heroku open '/.well-known/openid-configuration' # to see your openid-configuration
    

Create OIDC Identity Provider in AWS Console

  1. Visit IAM | Identity providers

  2. Click [Create Provider] button

  3. Enter

    Provider Type: "OpenID Connect"
    
    # base URL of server
    Provider URL: https://fast-atoll-98810.herokuapp.com
    
    # this should match `client_id` in `src/index.js`
    Audience: foo
    

  4. Click [Next]

  5. Click [Create]

  6. Visit IAM | Roles and click [Create Role] button

  7. Select Web Identity and select the Identity provider and Audience you specified in previous steps.

  8. Specify permissions

  9. Give the role a name (e.g. custom-oidc-role-example-01) note role ARN. e.g. arn:aws:iam::529276214230:role/custom-oidc-role-example-01

Login to Custom App and Get Temporary Security Credentials via assume-role-with-web-identity

  1. Visit login URL and enter any username and password

    heroku open '/auth?client_id=foo&response_type=id_token&scope=openid&nonce=123'
    

  2. Click [Sign-in] button

  3. Click [Continue] button

    note the id_token in the URL. This is the JWT Token we pass to assume-role-with-web-identity

  4. Call assume-role-with-web-identity with role-arn, role-session-name (can be anything), and web-identity-token (id_token from step above)

    aws sts assume-role-with-web-identity \
    --role-arn 'arn:aws:iam::529276214230:role/custom-oidc-role-example-01' \
    --role-session-name 'user01' \
    --web-identity-token '<id_token>'
    

  5. You can now use AccessKeyId, SecretAccessKey, and SessionToken in the response to access AWS services with the permissions provided by the custom-oidc-role-example-01 role

  6. As an example, see Creating a URL that Enables Federated Users to Access the AWS Management Console (Custom Federation Broker)

  7. To programmatically create URL, see Example Code Using Python