Skip to main content

Overview

The IdentityProviderServiceApi provides methods for managing identity providers in Zitadel. Identity providers enable users to authenticate using external services like Google, Azure AD, GitHub, and other OIDC/SAML providers.

Initialize the API

require 'zitadel/client'

client = Zitadel::Client::ApiClient.new
client.config.access_token = 'YOUR_ACCESS_TOKEN'

idp_api = Zitadel::Client::Api::IdentityProviderServiceApi.new(client)

Identity Provider Management

Returns an identity provider (social/enterprise login) by its ID. The provider can be of type Google, Azure AD, GitHub, etc.
request = Zitadel::Client::IdentityProviderServiceGetIDPByIDRequest.new(
  id: 'idp_123'
)

response = idp_api.get_idpby_id(request)

puts "IDP Name: #{response.idp.name}"
puts "IDP Type: #{response.idp.type}"
puts "Owner: #{response.idp.owner}"
id
string
required
The ID of the identity provider to retrieve

Identity Provider Types

OIDC Providers

Supports generic OIDC providers and specific implementations:
  • Google
  • Azure AD
  • GitHub
  • GitLab
  • Generic OIDC

SAML Providers

Supports SAML 2.0 identity providers:
  • Azure AD SAML
  • Generic SAML

OAuth Providers

Supports OAuth 2.0 providers:
  • Google
  • GitHub
  • GitLab
  • Azure AD

Example: Get Identity Provider Details

# Get an identity provider by ID
request = Zitadel::Client::IdentityProviderServiceGetIDPByIDRequest.new(
  id: 'idp_google_123'
)

response = idp_api.get_idpby_id(request)

puts "Identity Provider Details:"
puts "  Name: #{response.idp.name}"
puts "  Type: #{response.idp.type}"
puts "  State: #{response.idp.state}"

if response.idp.type == 'IDP_TYPE_OIDC'
  config = response.idp.oidc_config
  puts "  Client ID: #{config.client_id}"
  puts "  Issuer: #{config.issuer}"
  puts "  Scopes: #{config.scopes.join(', ')}"
elsif response.idp.type == 'IDP_TYPE_SAML'
  config = response.idp.saml_config
  puts "  Metadata URL: #{config.metadata_url}"
  puts "  Entity ID: #{config.entity_id}"
end

Example: Check Available Identity Providers

# This example shows how you might check which IDPs are configured
# Note: The stable API only provides get_idpby_id
# For listing IDPs, you would typically:
# 1. Get active IDPs from Settings Service
# 2. Or use the Beta IDP Service which has more methods

require 'zitadel/client'

settings_api = Zitadel::Client::Api::SettingsServiceApi.new(client)

# Get active identity providers for an organization
request = Zitadel::Client::SettingsServiceGetActiveIdentityProvidersRequest.new(
  organization_id: 'org_123'
)

response = settings_api.get_active_identity_providers(request)

response.identity_providers.each do |idp|
  puts "Available IDP: #{idp.name} (#{idp.id})"
  
  # Get detailed info for each IDP
  detail_request = Zitadel::Client::IdentityProviderServiceGetIDPByIDRequest.new(
    id: idp.id
  )
  
  detail_response = idp_api.get_idpby_id(detail_request)
  puts "  Type: #{detail_response.idp.type}"
  puts "  State: #{detail_response.idp.state}"
end

Integration with User Service

Identity providers are typically used in conjunction with the User Service for managing user links:
user_api = Zitadel::Client::Api::UserServiceApi.new(client)

# List IDP links for a user
request = Zitadel::Client::UserServiceListIDPLinksRequest.new(
  user_id: 'user_123'
)

response = user_api.list_idp_links(request)

response.result.each do |link|
  puts "Linked IDP: #{link.idp_id}"
  puts "  External User ID: #{link.user_id}"
  puts "  External Username: #{link.user_name}"
  
  # Get IDP details
  idp_request = Zitadel::Client::IdentityProviderServiceGetIDPByIDRequest.new(
    id: link.idp_id
  )
  
  idp_response = idp_api.get_idpby_id(idp_request)
  puts "  IDP Name: #{idp_response.idp.name}"
end

Identity Provider Configuration

OIDC Configuration

Typical OIDC identity provider configuration includes:
  • Issuer: The OIDC provider’s issuer URL
  • Client ID: OAuth client identifier
  • Client Secret: OAuth client secret
  • Scopes: Requested scopes (e.g., openid, profile, email)
  • Display Name Mapping: How to map the display name claim
  • Email Mapping: How to map the email claim

SAML Configuration

Typical SAML identity provider configuration includes:
  • Metadata URL: URL to the SAML metadata XML
  • Entity ID: SAML entity identifier
  • Binding: POST or Redirect binding
  • WithSignedRequest: Whether to sign SAML requests
  • Attribute Mapping: Mapping for email, display name, etc.

Identity Provider States

  • ACTIVE: The identity provider is active and can be used for authentication
  • INACTIVE: The identity provider is configured but not available for authentication

Example: Retrieve Multiple IDPs

# If you have a list of IDP IDs
idp_ids = ['idp_google_123', 'idp_azure_456', 'idp_github_789']

idp_ids.each do |idp_id|
  begin
    request = Zitadel::Client::IdentityProviderServiceGetIDPByIDRequest.new(
      id: idp_id
    )
    
    response = idp_api.get_idpby_id(request)
    
    puts "IDP: #{response.idp.name}"
    puts "  Type: #{response.idp.type}"
    puts "  State: #{response.idp.state}"
    puts "  Creation: #{response.idp.details.creation_date}"
  rescue => e
    puts "Error fetching IDP #{idp_id}: #{e.message}"
  end
end

Best Practices

  1. Cache IDP Information: Identity provider configurations don’t change frequently, so consider caching the results
  2. Error Handling: Always handle cases where an IDP might not exist or is inactive
  3. Security: Never expose IDP secrets in logs or client-side code
  4. User Experience: Show appropriate branding and labels based on IDP type
  5. Testing: Test the authentication flow for each configured IDP

Common Use Cases

Display Available Login Options

# Get active IDPs for login page
settings_api = Zitadel::Client::Api::SettingsServiceApi.new(client)

request = Zitadel::Client::SettingsServiceGetActiveIdentityProvidersRequest.new(
  organization_id: 'org_123',
  action_filters: ['IDP_ACTION_LINKING_ALLOWED']
)

response = settings_api.get_active_identity_providers(request)

login_options = response.identity_providers.map do |idp|
  detail = idp_api.get_idpby_id(
    Zitadel::Client::IdentityProviderServiceGetIDPByIDRequest.new(id: idp.id)
  )
  
  {
    id: idp.id,
    name: detail.idp.name,
    type: detail.idp.type,
    logo: get_idp_logo(detail.idp.type) # Your custom method
  }
end

puts "Available login options: #{login_options.inspect}"

Verify IDP Configuration

def verify_idp_config(idp_id)
  request = Zitadel::Client::IdentityProviderServiceGetIDPByIDRequest.new(
    id: idp_id
  )
  
  response = idp_api.get_idpby_id(request)
  idp = response.idp
  
  checks = {
    exists: true,
    active: idp.state == 'IDP_STATE_ACTIVE',
    has_client_id: false,
    has_issuer: false
  }
  
  if idp.type.include?('OIDC')
    config = idp.oidc_config
    checks[:has_client_id] = !config.client_id.nil? && !config.client_id.empty?
    checks[:has_issuer] = !config.issuer.nil? && !config.issuer.empty?
  end
  
  checks
rescue => e
  { exists: false, error: e.message }
end

result = verify_idp_config('idp_google_123')
puts "IDP Configuration: #{result.inspect}"

See Also

Build docs developers (and LLMs) love