Freika/dawarich · critical · Auth::VerifyAppleToken::InvalidToken
client_id not configured
Error message
client_id not configured
What it means
VerifyAppleToken resolves the expected Apple audience as @client_id || ENV['APPLE_BUNDLE_ID']; when both are blank it raises InvalidToken 'client_id not configured' before decoding anything. AppleID's verify! needs the client (audience) to check the aud claim, so verification is impossible without it - this error is always a server configuration problem, never a bad user token.
Source
Thrown at app/services/auth/verify_apple_token.rb:15
# frozen_string_literal: true
module Auth
class VerifyAppleToken
class InvalidToken < StandardError; end
def initialize(id_token, nonce: nil, client_id: nil)
@id_token = id_token
@nonce = nonce
@client_id = client_id
end
def call
raise InvalidToken, 'blank token' if @id_token.blank?
raise InvalidToken, 'client_id not configured' if effective_client_id.blank?
decoded = AppleID::IdToken.decode(@id_token)
verify_args = { client: effective_client_id }
verify_args[:nonce] = expected_nonce_hash if @nonce.present?
decoded.verify!(**verify_args)
log_missing_nonce_breadcrumb if @nonce.blank?
{
sub: decoded.sub,
email: decoded.email,
email_verified: decoded.email_verified?,
is_private_email: decoded.is_private_email?
}
rescue AppleID::IdToken::VerificationFailed, JSON::JWT::Exception => e
raise InvalidToken, e.message
endView on GitHub (pinned to 97fad417c5)
Solutions
- Set APPLE_BUNDLE_ID in the environment where the app runs (e.g. APPLE_BUNDLE_ID=com.example.app) and restart
- Or pass client_id explicitly when instantiating the service - required when web (Services ID) and native (bundle id) flows coexist
- Verify with a print/日志 of ENV['APPLE_BUNDLE_ID'] presence (never the value) in the target environment
- Add the variable to .env.example/deployment templates so new environments fail loudly at boot instead of at sign-in
Example fix
# before Auth::VerifyAppleToken.new(params[:id_token]).call # APPLE_BUNDLE_ID unset -> raises # after Auth::VerifyAppleToken.new(params[:id_token], client_id: ENV['APPLE_WEB_CLIENT_ID']).call # or ensure ENV['APPLE_BUNDLE_ID'] is set for this deployment
Defensive patterns
Strategy: validation
Validate before calling
# Fail fast at boot or entry, before any Apple round-trip raise 'APPLE_BUNDLE_ID env var is required for Apple sign-in' if ENV['APPLE_BUNDLE_ID'].blank? && client_id.blank?
Try / catch
begin
result = Auth::VerifyAppleToken.new(id_token, nonce:, client_id:).call
rescue Auth::VerifyAppleToken::InvalidToken => e
render json: { error: e.message }, status: :unauthorized # 'client_id not configured' = server misconfig, page the ops channel
end Prevention
- Add APPLE_BUNDLE_ID to .env.example and deployment checklists
- When supporting both native and web Apple sign-in, pass client_id explicitly per flow instead of relying on ENV
- Add a boot-time health check that fails startup when Apple sign-in is enabled but no client id resolves
When it happens
Trigger: Calling the Apple sign-in endpoint on a server where APPLE_BUNDLE_ID is unset (fresh deployment, missed .env entry, production-only omission) and the caller did not pass client_id: explicitly - e.g. a web client that should pass the Services-Apple-Web client id vs the native bundle id.
Common situations: New environment/missing ENV var after deploying, container orchestration not propagating APPLE_BUNDLE_ID, using the web (Services ID) flow where the bundle id is wrong anyway, credentials-based config where the var lives in credentials but was never exported to ENV.
Understand the failure class
Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.
Related errors
AI-assisted analysis of Freika/dawarich@97fad417c5 (2026-08-21).
Data as JSON: /api/errors/7abb5e02cb2af593.
Report an issue: GitHub.