What’s OIDC and why should you use it asap in your GitHub pipeline (keyless)



Table of contents

Hackers Paradise !
                        — “ 10 million credentials from GitHub were accessible in 2022 alone.” —


This is the shocking truth exposed in a recent
 report published
by secrets-management firm GitGuardian.            

That’s 5.5 out of every 1,000 commits to GitHub spilling secrets, putting applications & businesses at serious risk.
Scattered & hard-coded secrets across environments are one of the biggest threats for users, enterprises, & states.
.
These incidents that big corporations like Uber, NVIDIA, Lastpass, Samsung,Toyota, Dropbox and even Okta itself serve as a sobering reminder that leaked secrets are a gateway to high-profile breaches.

 

Infrastructure as Code

Terraform files pushed into GitHub are no exception as it had about 5.57 occurrences of secrets per 1,000 patches

 


Traditionally, connecting to cloud platforms involved using user or workload principal as shown below. While they served their purpose, they still represent a security risk.

  1. User based Authentication: Interactive login(GCP,Azure) or using access keys (AWS,OCI) => static

  2. Service principals: .i.e GCP (service account key file) , Azure (service principal password) => static

  3. Instance principals/managed identities: Only when Self-hosted runners are located in the cloud =>dynamic

  4. Assumed roles: long-lived secret (i.e AppRole for Hashicorp Vault) =>   semi-dynamic

Why is it wrong?

https://storage.googleapis.com/gweb-cloudblog-publish/images/workload_identity_federat.1000068220000678.max-2000x2000.jpg

  • Static credentials never expire which maximise vulnerability surface in case of leaks  

  • Management overhead: secure credential storage and rotation can be daunting for Ops teams

  • Cloud instance principals Self hosted runners, is an overkill especially if you deploy in MultiCloud

  • Even Dynamic secrets like AppRole (Vault) require static credentials to enable the feature(secret eng)    

OAuth `the Underlying Layer of OIDC`

It is impossible to talk about Open ID connect (OIDC) without first introducing OAuth2.0. And the best source for it is OktaDev team. So I’ll be using few illustrations from DevAdvocates Aaron Parecki and David Neal.

Note: The terminology can be super confusing but no worries, I will try my best to share what I learned. 

Back in the Stone AgeZynga Farmville 2 Login - July 15, 2023


Basic Authentication
In the old days, apps like Farmville required your Facebook username/password, in order to play. You not only let them access your account once, but they can keep the credentials forever—that’s like giving a shady dude your apartment key, hoping he won’t throw a wild party and make copies for all his friends to steal your stuff. So insane.

OAuth 2.0 to the rescue                                                            

      — “ How to let 3rd party applications access users data without users giving the passwords? ” —
                                                                           Skills-and-Challenges-Icon - LearningWorks for Kids

OAuth global standard answers this by letting apps receive an authorization key to access target data, eliminating the need for password sharing. Access is delegated, and user simply gives consent.

  • See how Google redirects all their apps login URLs into a single OAuth endpoint ‘accounts.google.com.
      


OAuth 2.0 Terminology

An Introduction to OAuth 2.0. A Quick Guide | by Kayathiri Mahendrakumaran  | DataDrivenInvestor
The OAuth2.0 authorization framework allows a 3rd-party application to access an HTTP service on behalf of a resource owner (via user consent) or by allowing an app to access on its own without knowing the user identity.
End-users provide their username/password at the Authorization server level which in turn replies to the Client with an authorization code allowing for another token exchange to obtain App access to target data.

Let’s review the terminology

Roles

                                What is Oauth 2.0 ? A Comprehensive Analysis of OAuth 2.0 Authentication  Vulnerabilities and Prevention - TheHackerStuff

  • Resource Owner: You! or the owner of the identity, data, and actions on the account resources.

  • Client: The application that wants to use the resources on your behalf (i.e GitHub workflow)

    • Client ID: ID used to identify the Client with the Authorization Server (can be visible).

    • Client Secret: Password given by the Authorization Server to a client for private exchange.

    • Client types (by secret
      retention)

      • Confidential client: Server
        environments (.NET,java) > can hold secrets

      • Public client: Web, Single
        Page App, JScript,
        Mobile aps > too open to keep
        secrets

  • Authorization Server: Service that manages Resource Owner authorization in target platform(i.e AD).

  • Resource Server: API allowing to use/manage resources belonging to the Resource Owner (i.e AZ API)

App registration (Day1):

At the very beginning the Client (app) needs to register at the Authorization Server to established a working relationship. That’s when a redirect URI is set, and Client ID/Secret are generated by the Authorization server.

Payload Items
             

  • Scope: Type of permission the Client wants, such as access to data or to perform actions. See Google’s

  • Redirect URI/Callback: URL, Authorization Server redirects a Resource Owner back to after consent.

  • Response/Grant Type: Common
    type is
    code, where the
    Client expects an Authorization
    Code
    .

  • Authorization
    Code:
    A grant code Client exchanges with the
    Authorization Server for an Access
    Token.

  • Consent: Resource Owner agrees to delegate access to a Client and informs Authorization Server.

  • State: Random string generated by the app, which allows to confirm that Auth server reply wasn’t forged.

  • Access Token: A short-lived key the Client obtains to use the Owner’s resources in the target platform.

  • Refresh Token: Sent to the Client by the auth server to refresh a token when the current one expires.


Communication Channels

  • Front channel: Web browser to Server (Auth/API). Can not carry secrets only IDs/scopes [Public client].

  • Back channel: Server(Client) to server (Auth/API). Default channel for secret exchange (token).   

OAuth 2.0 Workflow

Let’s break down the OAuth flow ! Assuming we’ve got our app registered with client ID and secret in place.
This Yelp Auth2 flow comes from Nate Barbettini (see video

  1. Yelp app(Client) sends an API request to the Authorization server containing client info to get access.
                                

  2. Authorization server asks consent from the Resource Owner to delegate access to Yelp. User says yes.

  3. Authorization server then sends back an Authorization code to Yelp app via the callback URL.
                                                    

  4. Yelp (Client) now sends the code, client secret and client Info to the Auth server in exchange for a token.
                                

  5. The Authorization server validates the code and client info, then sends back the Access Token to Yelp.

  6. Finally, The app(Client) wraps the access token in an API request to the Resource server & gets access to the user’s Gmail contacts.
                                   

What is OIDC?


OpenID Connect
is an authentication protocol built on top of OAuth 2.0 by adding an identity layer on top of it.

OAuth 2.0 and OpenID Connect


  • It provides information about the user, as well as enables clients to establish login sessions.

  • OAuth 2.0 provides API security via scoped access tokens, and OpenID Connect provides user authentication and SSO functionality on top of OAuth’s secure Authorization.

OIDC .vs OAuth 2.0 (Permission vs Identity)

 
Hotel Analogy(OAuth 2.0)


Let’s say you go and check in at a Hotel lobby:

  1. You (or Client on behalf of Resource Owner)Show your ID and credit card. 

  2. Receptionist (Authorization server) gives you back a key card (Access token).

  3. You take that card and go to the room then swipe it on the door (Resource API), door opens.

The door doesn’t need to know who is using the key card(delegated access). Anyone can enter with the card.

  • In Summary

    • OAuth is about accessing APIs (Authorisation), OIDC is about Identifying users (Authentication).

    • OAuth 2.0 is not an authentication flow as opposed to OIDC that verifies the identity of and end-user.


    What OIDC adds

    1. User Info endpoint: For more user information
    2. Standard set of scopes and standardized implementation

    3. ID Token: 

    • Is the core of OIDC as it contains information about the user who signed which is provided to the client.

    • This token is encoded and signed using JWT (Jason Web Token) format, which is readable by the client.

    • In a OIDC flow, the client requests an ID token along with an access token.

    • The data inside the ID Token is called => claims.

    OIDC Authentication flow

    • Same as OAuth’s plus a new open_id scope and the return of a Token ID to Identify the logged-in user.

    • See new user information gathered in step 6 below:

    OIDC in GitHub Actions


    OIDC allows GitHub Actions workflows to access resources in your cloud provider, using ephemeral tokens for each pipeline run directly from your cloud provider.

    • The ID Token, however, is here generated by GitHub’s Identity provider, not by the cloud provider.

    • The Cloud validates ID Token claims based on
      the mapped cloud identity then provides an access token.

    Benefits:

    • Seamless authentication with cloud providers without storing long-lived secrets.

    • Enables Cloud admins to rely on their provider’s security mechanisms for minimal access to resources.

    • There is no duplication of secret management in GitHub and the cloud.

    • Using OIDC with Workload Identity Federation is a big win in terms reduced maintenance (rotation).



    Steps


    • You will first need to
      configure your cloud provider to trust GitHub’s OIDC as a federated identity (set up the OIDC trust),
      then update your workflow to authenticate using
      tokens.

    Eliminate Static Keys for Cloud Resources Access Using OpenID Connect | by  Gonzalo Peci | Trade Republic Engineering

    Workflow:

    1. Workflow asks GitHub Identity provider
      for a token

    2. GitHub IdP gives back ID token to the
      workflow runner

    3. Workflow sends a request with the
      JWT (ID token) to the Cloud provider Authorization Server (is Az AD)

    4. Cloud provider checks the token & validates the claims against the cloud role definition defined in WIF claim.

    5. Cloud provider then gives back access &
      refresh tokens to use the resources in the workflow scope

    Note: To control how your cloud provider issues access tokens, you must define at least one condition, so that untrusted repositories can’t request access tokens for your cloud resources.

    How to check my git actions claims?


    The actions-oidc-debugger action, is the perfect tool to print your ID token (JWT) claims.
    Here’s an excerpt of my repo claims:

    Example: OIDC Token claims for “brokedba”s github actions workflow

    { "actor": "brokedba", "aud": "https://github.com/brokedba", "environment": "gcp-labs", "event_name": "push", "iss": "https://token.actions.githubusercontent.com", "job_workflow_ref": "brokedba/terraform-examples/.github/workflows/..", "ref": "refs/heads/git_actions", "ref_type": "branch", "repository": "brokedba/terraform-examples", "repository_owner": "brokedba", snip ... "sub": "repo:brokedba/terraform-examples:environment:gcp-labs", <<--- "workflow": "Terraform_gcp_vpc", snip ... }


    Note: Standard claims include audience, issuer, and subject. Full description can be found here > Github Doc

    MultiCloud keyless access examples (Azure/AWS/GCP)

    • Azure

    Set up OIDC trust in Azure by creating Workload identity federation for github actions (AD application registration)

    1. The GitHub Actions workflow requests an ID token from the external IdP (GitHub ID provider).

    2. The GitHub ID Provider issues the ID token to the external workload (GitHub actions).

    3. The login action in GitHub actions workflow sends token to Microsoft identity requesting an access token.

    4. Microsoft identity checks the trust relationship on the app registration (or managed Identity) and validates the ID token against the OIDC issuer URL (token.*.githubcontent.com) on the GitHub IdP.

    5. When the checks are satisfied, Microsoft identity platform sends an access token to the GitHub workflow.

    6. The Git Actions workflow accesses Azure resources using the access token to deploy in azure.

    Official OIDC login action
       Owner avatar  Azure/login
       

     

    • AWS

    Secretless connections from GitHub Actions to AWS using OIDC

    1. In AWS, set up OIDC trust between aws role and the GitHub ID token used in your GitHub Actions workflow.

    2. Action like configure-aws-credentials, will request a signed JWT with multiple claims during an workflow run.

    3. GitHub OIDC provider issues a signed JWT with multiple claims to the GitHub actions workflow.

    4. The action sends the JWT and the requested role to AWS.

    5. The JWT is validated in AWS and AWS sends a short-lived access token in exchange. With this token, it’s possible to access AWS resources.

    Official OIDC login action
      Owner avatar   aws-actions/configure-aws-credentials


    • GCP

    How does the GCP Workload Identity Federation work with Github Provider? |  by Pradeep Kumar Singh | Google Cloud - Community | Medium

    1. Set up OIDC trust by creating Workload Identity Pool, Workload Identity Provider and IAMs.

    2. A GitHub Action like google-github-actions/auth will request a signed JWT with multiple claims during an action job/workflow run.

    3. The action sends the JWT to GCP security Token Service to get a federated token in return.

    4. The auth action exchanges federated token received in previous step to get IAM access token.

    5. Using the access token received in step 4 workflow makes an API request to GCP for listing instances

    Official OIDC login action
      Owner avatar   google-github-actions/auth

    CONCLUSION

    • We just covered the exciting journey from the birth of OAuth to secretless CI/CD authentication to Cloud.

    • Adopting OIDC will fortify your GitHub pipelines, so you can kiss your leaked credentials good bye.

    • Now, go cleanup all you repos because OIDC is the Mr Clean of Authentication your company hoped for!

    • I hope Oracle Cloud will join the party, and offer support for GitHub OIDC provider.

    • Next, I will write detailed guides about Multicloud deployment pipelines in GitHub actions,
                                                                         (using OIDC of course).


                   Stay tuned