Identity and access control
By the end of this module you will be able to:
- Distinguish OAuth 2.0 flows and select the appropriate flow for a given client type
- Explain the structural difference between OAuth 2.0 and OpenID Connect
- Decode and validate a JWT and identify common misconfiguration risks
- Apply secure session management cookie attributes to browser-based applications

Okta support infrastructure compromise, January 2022
Lapsus$ and the Okta contractor access
In January 2022, the Lapsus$ extortion group disclosed that they had compromised Okta’s customer support infrastructure. A Sitel (third-party contractor) support engineer’s laptop had been accessed via a remote desktop tool, and the attacker maintained access for approximately five days before Okta detected and terminated the session. Okta later confirmed that up to 366 customer tenants were potentially affected.
The incident was not a failure of Okta’s core identity infrastructure: it was a failure at the access control boundary around privileged tooling used by a third-party contractor. The attacker’s use came not from breaking OAuth tokens but from using the support engineer’s legitimately provisioned access to Okta’s internal tooling.
The lesson: privilege assignment to contractors and support roles must be scoped to the minimum necessary function, time-limited, and subject to session recording.
OAuth 2.0 fundamentals
OAuth 2.0, defined in RFC 6749 (2012), allows a resource owner to grant a third-party client limited access to a protected resource without sharing their credentials. It delegates authorisation, not authentication. Four roles are involved: the Resource Owner (user who owns the data), the Client (application requesting access), the Authorisation Server (issues tokens after authenticating the user), and the Resource Server (hosts protected resources and validates tokens).
Authorization Code with PKCE (RFC 7636) is the correct flow for all public clients: single-page applications, mobile apps, and CLI tools where a client secret cannot be stored securely. The client generates a random code_verifier, hashes it with SHA-256 to produce a code_challenge, and includes the challenge in the authorisation request. The server stores it and later verifies the original verifier during the token exchange. An intercepted authorisation code is useless without the verifier, which never left the client device.
Client Credentials flow is for machine-to-machine communication where there is no human resource owner. A backend service authenticates directly with the authorisation server using its own client_id and client_secret, receiving an access token scoped to its permitted operations.
The Implicit flow is deprecated in RFC 9700 (OAuth 2.0 Security Best Current Practice) because access tokens appear in the URL fragment, exposing them to referrer headers and browser history. The Resource Owner Password Credentials flow requires the app to handle raw user passwords, defeating the purpose of OAuth delegation.
With an understanding of oauth 2.0 fundamentals in place, the discussion can now turn to oauth 2.0 versus openid connect, which builds directly on these foundations.
OAuth 2.0 versus OpenID Connect
OpenID Connect (OIDC), standardised by the OpenID Foundation in 2014, is an identity layer built on top of OAuth 2.0. OAuth 2.0 handles authorisation (what you can do); OIDC handles authentication (who you are). OIDC adds an ID token, a UserInfo endpoint, and standardised claims about the authenticated user.
An OAuth 2.0 access token grants access to a resource. It says nothing about who the user is and should not be parsed to determine user identity. An OIDC ID token is a JWT carrying claims about the authenticated user: sub (subject identifier), email, name, iat (issued at), exp (expiry), and others. It is intended for the client, not the resource server.
Many developers use an access token to retrieve user identity by calling a /me endpoint and treating the response as authoritative. The correct pattern is to use the OIDC ID token for identity assertions at the client and the access token exclusively for authorised API calls. Conflating the two causes subtle security failures when token scopes or lifetimes differ.
With an understanding of oauth 2.0 versus openid connect in place, the discussion can now turn to saml 2.0 for enterprise sso, which builds directly on these foundations.
SAML 2.0 for enterprise SSO
Security Assertion Markup Language (SAML) 2.0, standardised by OASIS in 2005, remains dominant for enterprise single sign-on in environments with large on-premises directories such as Microsoft Active Directory Federation Services. SAML uses XML-based assertions: authentication assertions (proves login), attribute assertions (carries user attributes), and authorisation decision assertions (states what the user may do).
SAML's weakness relative to OIDC is complexity. In 2018, researchers disclosed XML signature wrapping vulnerabilities affecting Duo Security, OneLogin, and GitHub Enterprise (CVE-2018-7340 and related). An attacker with any valid account could forge assertions for arbitrary users by manipulating the XML structure. Libraries implementing SAML must be kept current and validated against known wrapping attack patterns.
With an understanding of saml 2.0 for enterprise sso in place, the discussion can now turn to jwt structure and validation, which builds directly on these foundations.
JWT structure and validation
A JSON Web Token consists of three Base64URL-encoded segments separated by periods: header.payload.signature. The header specifies the token type and signing algorithm. The payload carries claims: sub (subject), iss (issuer), aud (audience), exp (expiry), iat (issued at), and scope. The signature is a cryptographic proof over the header and payload; for RS256 it uses the authorisation server's private key and is verified by the resource server using the corresponding public key from the server's JWKS endpoint.
RFC 9068 defines the JWT Profile for OAuth 2.0 Access Tokens. Receivers must validate: token signature, iss against an allowlist, aud against the current service identifier, exp against current time, and nbf (not before) if present.
The alg:none attack is well-documented: some JWT libraries accept a token with "alg":"none" in the header and skip signature verification entirely. Libraries that accept both HS256 and RS256 can also be confused into verifying an RS256 token using the public key as an HMAC secret. Always configure JWT verification to accept only the specific algorithm your authorisation server uses.
With an understanding of jwt structure and validation in place, the discussion can now turn to session management and privilege escalation, which builds directly on these foundations.
“The authorization server MUST NOT issue access tokens and other applicable credentials to any client that does not perform client authentication as described in the grant type specification when the client is a confidential client. ... Authorization Code grant with PKCE MUST be used for public clients that cannot hold a client secret.”
RFC 6749, Section 4: Obtaining Authorisation; supplemented by RFC 9700 OAuth 2.0 Security Best Current Practice
“Access control policies should be based on the principle of least privilege: subjects should be granted only the minimum access necessary to perform their legitimate functions. Privileged access should be time-limited, monitored, and regularly reviewed.”
NIST SP 800-53r5, AC-6: Least Privilege and AC-2: Account Management (2020) - AC-6 Least Privilege
Session management and privilege escalation
Browser-based sessions use cookies. The baseline security attributes are: HttpOnly (cookie inaccessible to JavaScript, prevents XSS theft), Secure (transmitted only over HTTPS), and SameSite=Strict or Lax (prevents CSRF by blocking cross-site cookie submission). The __Host- cookie prefix forces Secure and prevents domain-scoped setting.
Session fixation occurs when an attacker sets a session token before the user authenticates and then waits. The defence is to issue a new session token immediately after successful authentication. Session lifetime must be bounded with absolute timeouts in addition to idle timeouts.
Privilege escalation attacks exploit authorisation logic. Vertical escalation: a low-privilege user gains high-privilege functions by modifying a hidden form field or request parameter containing role data. Horizontal escalation: a user accesses another user's resources at the same privilege level by changing an identifier in the URL. Both are prevented by server-side authorisation checks on every request, never trusting client-supplied role or permission data.
Common misconception
“Any valid OAuth 2.0 flow is equally secure for public clients.”
The Implicit flow is deprecated in RFC 9700 because access tokens appear in the URL fragment, exposing them to browser history and referrer leakage. The Resource Owner Password Credentials flow requires the client to handle raw user passwords. For public clients that cannot store a client secret, Authorization Code with PKCE is the only currently recommended approach.
Common misconception
“Multi-factor authentication makes an account immune to credential-based attacks.”
MFA significantly raises the bar for credential-based attacks but does not eliminate them. Push notification MFA is vulnerable to MFA fatigue attacks: an attacker with valid credentials bombards the user with push notifications until the user approves one out of frustration. Microsoft reported in 2022 that MFA fatigue was used in the Cisco Duo attack and multiple Exchange Online compromises. Phishing-resistant MFA (FIDO2 passkeys, hardware security keys) is immune to MFA fatigue and real-time phishing because the authentication credential is domain-bound and cannot be relayed. For privileged accounts and high-risk actions, phishing-resistant MFA should be required; push notification MFA is a meaningful improvement over SMS but is not equivalent.
A mobile banking application cannot securely store a client secret. It must allow users to log in and grant the app access to read their transaction history. Which OAuth 2.0 flow is most appropriate?
A JWT issued by your authorisation server has its 'aud' claim set to '*'. What is the primary security risk?
An organisation deploys a CIAM (Customer Identity and Access Management) system for their e-commerce platform. They configure: password authentication with minimum 8 characters; email-based OTP as a second factor; account lockout after 10 failed attempts; session tokens with 30-day expiry and no re-authentication requirement for account changes. A security review flags three issues. Which is the highest severity and why?
Key takeaways
- OAuth 2.0 handles authorisation; OIDC adds authentication on top. Never use an access token as proof of identity at the client.
- Authorization Code with PKCE is the correct flow for public clients. Implicit flow is deprecated. Client Credentials is for machine-to-machine scenarios only.
- JWTs must be validated against a fixed algorithm allowlist. Never accept alg:none. Algorithm confusion attacks (RS256 verified as HMAC with the public key) are documented and exploited.
- Cookie-based sessions require HttpOnly, Secure, and SameSite attributes as a baseline. Issue a new session token immediately after authentication to prevent session fixation.
- Privilege escalation exploits authorisation logic. Enforce server-side authorisation checks on every request; never trust client-supplied role or permission data.
You now understand how identity flows work and where they break. But even with strong authentication, the application code itself can be vulnerable. What are the OWASP Top 10 vulnerabilities, and how do you write code that eliminates them? Module 12 covers web application security.
Standards and sources cited in this module
RFC 6749, The OAuth 2.0 Authorization Framework
Foundational OAuth 2.0 specification defining roles, flows, and grant types.
RFC 7636: PKCE for OAuth Public Clients
PKCE mechanism: code_verifier generation and code_challenge derivation.
RFC 9068: JWT Profile for OAuth 2.0 Access Tokens
Mandatory validation requirements for JWT access tokens: iss, aud, exp, nbf.
OWASP Session Management Cheat Sheet
Cookie attribute guidance, session lifetime, and session fixation defence.
NIST SP 800-63C: Digital Identity Guidelines, Federation
Federation assertion requirements including short-lived assertions and audience restrictions.

