Validate user claims from ALB terminated IdP in Rails

By Ryan Romanchuk
On

Offloading authentication

On successful authentication, ALB will forward claims via the x-amzn-oidc-data header and the users cognito id x-amzn-oidc-identity

This is not the same verification flow as traditional cognito/oauth2 since the regional load balancer is the one minting the token. See: User claims encoding and signature verification for details

Dig the kid from the encoded payload to then fetch the public key for verification.

class ValidateUserClaims < Service
  attr_reader :claims

  let(:jwt_headers) { claims.split('.')[0] }
  let(:decoded_jwt_headers) { Base64.decode64(jwt_headers) }
  let(:decoded_json) { JSON.parse(decoded_jwt_headers) }

  let(:kid) { decoded_json['kid'] }
  let(:url) { "https://public-keys.auth.elb.us-east-1.amazonaws.com/#{kid}" }
  let(:pub_key) { Faraday.get(url).body }

  def initialize(claims)
    super()
    @claims = claims
  end

  def call
    return false unless claims.present?

    JWT.decode claims, pub_key, nil, { algorithm: 'ES256' }
  end
end

Usage

raise("Straight to jail") unless ValidateUserClaims.call(request.headers['x-amzn-oidc-data'])
talk