What I want to do:
What I am trying to do is, a user registers via my flask endpoint lets call it /register, which works on localhost:5000, a dokerized keycloak is being used to handle everything related to authentication and autherization via port 9090, I then generate a link, that includes elements from CIBA so that the user authenticates himself after he recieves the link via email my presumed code to generate the email to send
auth_req_id = response["auth_req_id"] if "auth_req_id" in response else "None"
verification_link = config.decrypted_login_ciba_url + "?token=" + auth_req_id + "&email=" + user_email
The CIBA part is not working at all, when I attempt to get the auth_req_id via this code
ciba_request_url = "{}realms/{}/protocols/openid-connect/ext/ciba/auth".format(decrypted_keycloak_server_url, decrypted_keycloak_master_realm)
payload = {
"client_id": decrypted_keycloak_client_id,
"client_secret": decrypted_keycloak_client_secret_key,
"login_hint": login_hint,
"scope": "profile",
"binding_message": "this is a binding message"
}
headers = {"Content-Type": "application/x-www-form-urlencoded"}
response = requests.request(method="POST", url=ciba_request_url, headers=headers, data=payload)
Its failing and returning an error without any logs in the keycloak server. After attempting to call the keycloak endpoint directly from postman I got the following error:
{
"error": "server_error",
"error_description": "Failed to send authentication request"
}
Do note that if I supply the login_hint of a user that does not exist, I get the following expected error, which means the keycloak server is functioning correctly:
{
"error": "invalid_request",
"error_description": "invalid user"
}
How I configured stuff:
I have set up my keycloak using this docker compose:
version: '3'
services:
dev-keycloak:
image: quay.io/keycloak/keycloak:18.0.2
command:
- start-dev
# env_file:
# - basekeycloakenviroment.env
environment:
- KEYCLOAK_ADMIN=admin
- KEYCLOAK_ADMIN_PASSWORD=admin
- KC_HTTP_ENABLED=true
- KC_FEATURES="preview, account-api, account2, account3, admin-api, admin-fine-grained-authz, admin2, authorization, ciba, client-policies, client-secret-rotation, declarative-user-profile, device-flow, docker, dpop, dynamic-scopes, fips, impersonation, js-adapter, kerberos, linkedin-oauth, map-storage, multi-site, par, preview, recovery-codes, scripts, step-up-authentication, token-exchange, transient-users, update-email, web-authn"
- KC_SPI_CIBA_AUTH_CHANNEL_CIBA_HTTP_AUTH_CHANNEL_HTTP_AUTHENTICATION_CHANNEL_URI=http://host.docker.internal:5000/login-callback
- JAVA_OPTS_APPEND=-Dkeycloak.profile.feature.admin_fine_grained_authz=enabled
ports:
- "9090:8080"
volumes:
- keycloak_data:/opt/keycloak/data
networks:
- keycloaknetwork
networks:
keycloaknetwork:
driver: bridge
volumes:
keycloak_data:
name: keycloak_data_volume
I have also set up my CIBA configurations in the keylcloak UI as follows:

I set up the endpoint login-callback in my flask app as follows(its a simple testing endpoint):
class CIBAResource2(Resource):
def post(self):
# Here, you would handle the notification from Keycloak.
# For now, let's just print the received data to the console.
data = request.json
print("Received notification from Keycloak:", data)
return "Notification received", 201
api.add_resource(CIBAResource2, '/login-callback')
my flask app can communicate with the dockerized keycloak normally without any problem, I can authenticate a user and everything without using CIBA, via basic username/password that generates a token.
The issue:
Now the opposite is not true especially when testing CIBA:
First attempt, I tested via the flask application, and it returned an error, no logs showed on keycloak.
Second attempt, I checked via postman directly using the keycloak pre-built endpoints, this is the curl I tested via postman:
curl --location --request POST 'http://localhost:9090/realms/realm-1/protocol/openid-
connect/ext/ciba/auth' \
--header 'User-Agent: Apidog/1.0.0 (https://apidog.com)' \
--data-urlencode 'client_id=realm-1-client-1' \
--data-urlencode 'client_secret=yQ7IJglc3WZ3M3PBkt9CHp1gYP0freUC' \
--data-urlencode 'login_hint=employee1' \
--data-urlencode 'scope=profile email' \
--data-urlencode 'binding_message=callback'
it also did not work, but returned this error with status code= 503 and no logs were showing on keycloak:
{
"error": "server_error",
"error_description": "Failed to send authentication request"
}
After doing some digging, I discovered this stackoverflow question: Keycloak CIBA Authentication fails with "Failed to send authentication request" for the same error, but it did not help at all
Third attempt, I had the idea to test the curl for localhost:5000/login-callback directly from dockerized keycloak terminal, at first it did not work, the reason why it did not work is I discovered that docker quarantines the container inside, while I exposed port 8080 and mapped it to 9090 for communicting into the docker container, localhost does not work when communicating from the container to the outside, this is where I discovered host.docker.internal. When I called via curl http://host.docker.internal:5000/login-callback I managed to get a result back, and it worked at least in curl in the docker container terminal.
After the third solution, I thought perhaps I need to change KC_SPI_CIBA_AUTH_CHANNEL_CIBA_HTTP_AUTH_CHANNEL_HTTP_AUTHENTICATION_CHANNEL_URI = localhost:5000/login-callback to host.docker.internal:5000/login-callback and I repeated the same attempted, but still it does not work, when I attempt to apply the keycloak endpoint I still get the same error, so, what am I doing wrong here, I think the issue is related to Docker or something, or perhaps its related to CIBA configurations, or even both, but I cant put my finger on what it is, this has been the 5th day attempting to figure it out.