View on GitHub

Lightspeed core service

Lightspeed core service

Red Hat Identity Authentication (rh-identity)

Red Hat Identity header authentication for deployments behind Red Hat Hybrid Cloud Console infrastructure (e.g., console.redhat.com, Insights). This module validates the x-rh-identity header provided by Red Hat’s authentication proxy.

Overview

The rh-identity module:

  1. Extracts the x-rh-identity header from incoming requests
  2. Base64 decodes and parses the JSON payload
  3. Validates the identity structure based on type (User or System)
  4. Optionally validates service entitlements
  5. Extracts user identity for downstream use

Architecture

┌─────────────────┐      ┌──────────────────┐      ┌─────────────────────┐
│   Client/RHEL   │──────▶  Red Hat Auth    │──────▶  Lightspeed Stack   │
│     System      │      │     Proxy        │      │   (rh-identity)     │
└─────────────────┘      └──────────────────┘      └─────────────────────┘
                               │                           │
                               │ Adds x-rh-identity        │ Validates header
                               │ header to request         │ Extracts identity
                               ▼                           ▼

The authentication proxy (part of Red Hat’s infrastructure) authenticates users via SSO or systems via certificate authentication, then injects the x-rh-identity header containing the verified identity information.

Configuration

Basic Configuration

authentication:
  module: rh-identity

With Entitlement Validation

authentication:
  module: rh-identity
  rh_identity_config:
    required_entitlements:
      - rhel
      - insights

Configuration Options

Option Required Default Description
required_entitlements No [] List of service entitlements to require

When required_entitlements is configured, ALL listed entitlements must be present and entitled in the identity header. Omit this field to disable entitlement validation entirely.

Identity Types

The x-rh-identity header supports two identity types, each with different structure and use cases.

User Identity

Console users authenticated via Red Hat SSO. Used when humans access services through the Hybrid Cloud Console.

Identity extraction:

Header structure:

{
  "identity": {
    "account_number": "123456",
    "org_id": "654321",
    "type": "User",
    "user": {
      "user_id": "abc123",
      "username": "user@example.com",
      "is_org_admin": false,
      "is_internal": false,
      "locale": "en_US"
    }
  },
  "entitlements": {
    "rhel": {"is_entitled": true, "is_trial": false},
    "insights": {"is_entitled": true, "is_trial": false},
    "ansible": {"is_entitled": false, "is_trial": false}
  }
}

Available User fields:

Field Type Description
user_id string Unique user identifier
username string User’s email or username
is_org_admin boolean Whether user is an organization admin
is_internal boolean Whether user is a Red Hat internal user
locale string User’s locale preference

System Identity

Certificate-authenticated RHEL systems. Used when RHEL hosts access services directly (e.g., Insights client, subscription-manager).

Identity extraction:

Header structure:

{
  "identity": {
    "account_number": "123456",
    "org_id": "654321",
    "type": "System",
    "system": {
      "cn": "c87dcb4c-8af1-40dd-878e-60c744edddd0",
      "cert_type": "system"
    }
  },
  "entitlements": {
    "rhel": {"is_entitled": true, "is_trial": false}
  }
}

Available System fields:

Field Type Description
cn string Certificate Common Name (system UUID)
cert_type string Certificate type (usually “system”)

Common Identity Fields

Both identity types share these top-level fields:

Field Type Description
account_number string Red Hat account number
org_id string Organization ID
type string Identity type: “User” or “System”

Entitlements

Entitlements represent service subscriptions. Each entitlement has:

Field Type Description
is_entitled boolean Whether the account has this entitlement
is_trial boolean Whether this is a trial entitlement

Common entitlement names:

Accessing Identity Data in Application

The module stores the parsed identity data in request.state.rh_identity_data for downstream access:

from fastapi import Request

async def my_endpoint(request: Request):
    rh_identity = request.state.rh_identity_data
    
    # Get organization ID
    org_id = rh_identity.get_org_id()
    
    # Check specific entitlement
    has_insights = rh_identity.has_entitlement("insights")
    
    # Get user info
    user_id = rh_identity.get_user_id()
    username = rh_identity.get_username()

Available Methods

Method Returns Description
get_user_id() str User ID or system CN
get_username() str Username or account number
get_org_id() str Organization ID
has_entitlement(service) bool Check single entitlement
has_entitlements(services) bool Check ALL entitlements in list

Request Examples

Creating a Test Header

# User identity
IDENTITY='{
  "identity": {
    "account_number": "123456",
    "org_id": "654321",
    "type": "User",
    "user": {
      "user_id": "test-user-id",
      "username": "testuser@example.com"
    }
  },
  "entitlements": {
    "rhel": {"is_entitled": true, "is_trial": false}
  }
}'

# Base64 encode
HEADER=$(echo -n "$IDENTITY" | base64)

# Make request
curl http://localhost:8080/v1/query \
  -H "Content-Type: application/json" \
  -H "x-rh-identity: $HEADER" \
  -d '{"query": "Hello"}'

System Identity Example

# System identity
IDENTITY='{
  "identity": {
    "account_number": "123456",
    "org_id": "654321",
    "type": "System",
    "system": {
      "cn": "c87dcb4c-8af1-40dd-878e-60c744edddd0"
    }
  },
  "entitlements": {
    "rhel": {"is_entitled": true, "is_trial": false}
  }
}'

HEADER=$(echo -n "$IDENTITY" | base64)

curl http://localhost:8080/v1/query \
  -H "Content-Type: application/json" \
  -H "x-rh-identity: $HEADER" \
  -d '{"query": "Hello"}'

Error Responses

Status Condition Response
401 Missing x-rh-identity header {"detail": "Missing x-rh-identity header"}
400 Invalid base64 encoding {"detail": "Invalid base64 encoding in x-rh-identity header"}
400 Invalid JSON {"detail": "Invalid JSON in x-rh-identity header"}
400 Missing identity field {"detail": "Missing 'identity' field"}
400 Missing identity type {"detail": "Missing identity 'type' field"}
400 Missing user for User type {"detail": "Missing 'user' field for User type"}
400 Missing user_id in user {"detail": "Missing 'user_id' in user data"}
400 Missing username in user {"detail": "Missing 'username' in user data"}
400 Missing system for System type {"detail": "Missing 'system' field for System type"}
400 Missing cn in system {"detail": "Missing 'cn' in system data"}
400 Missing account_number for System {"detail": "Missing 'account_number' for System type"}
400 Unsupported identity type {"detail": "Unsupported identity type: X"}
403 Missing required entitlements {"detail": "Missing required entitlement: rhel"}

Deployment Considerations

Behind the Hybrid Cloud Console

When deployed behind console.redhat.com or similar Red Hat infrastructure:

  1. The authentication proxy handles all authentication
  2. The x-rh-identity header is automatically injected
  3. Configure Lightspeed Stack to trust this header

Security Notes

Local Development

For local testing without the authentication proxy, you can manually create headers using the examples above. Consider using noop module instead for simpler local development.

Troubleshooting

Common Issues

Issue Cause Solution
401 errors Header not being forwarded Check proxy/ingress configuration
400 errors Malformed header Validate JSON structure, check base64 encoding
403 errors Missing entitlements Verify account has required subscriptions
Wrong user ID Using System identity Check identity type in header

Debugging

Enable debug logging to see identity extraction:

service:
  color_log: true
  log_level: DEBUG

Look for log entries like:

RH Identity authenticated: user_id=abc123, username=user@example.com