bot-idp
is an OpenID Connect Provider that authenticates user browser
via proof-of-work.
It is intended to slow down (AI) bots and scrapers.
bot-idp
works with any reverse-proxy
that supports OpenID Connect protocol:
- End user navigates to a website or web application via a browser.
reverse-proxy
checks session cookie and proxies to the backend if it is valid.- Otherwise
reverse-proxy
redirects user to thebot-idp
. bot-idp
authenticates the User by running a piece of code in their browser to obtain proof-of-work and use it to issue an Identity Token.bot-idp
responds with an Identity Token and an Access Token.- The
reverse-proxy
can send a request with the Access Token to the User device (not implemeneted). - The UserInfo Endpoint returns Claims about the End-User (not implemeneted).
Run from source repository:
DEBUG=1 \
DIFFICULTY=16 \
ADDRESS=:4159 \
SECRET=$(head -c 32 /dev/urandom | base64) \
CLIENT_ID=bot-idp \
CLIENT_SECRET=secret1 \
ISSUER=http://localhost:4159 \
EXPIRES_IN=3600 \
go run .
2025/03/23 21:21:08 DEBUG Keys signingKeyPub=11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo
2025/03/23 21:21:08 INFO Listen address=:4159
or via Docker:
docker pull ghcr.io/alexanderyastrebov/bot-idp:latest
docker run -p 4159:4159 \
-e DEBUG=1 \
-e DIFFICULTY=16 \
-e ADDRESS=:4159 \
-e SECRET=$(head -c 32 /dev/urandom | base64) \
-e CLIENT_ID=bot-idp \
-e CLIENT_SECRET=secret1 \
-e ISSUER=http://localhost:4159 \
-e EXPIRES_IN=3600 \
ghcr.io/alexanderyastrebov/bot-idp
Increase DIFFICULTY
to harden the challenge.
Run oauth2-proxy using example config:
docker run --rm -it --network=host -v ./doc/oauth2-proxy.cfg:/oauth2-proxy.cfg quay.io/oauth2-proxy/oauth2-proxy:v7.8.1 --config /oauth2-proxy.cfg --cookie-secret=$(head -c 32 /dev/urandom | base64 | tr '/+' '_-')
[2025/03/23 21:42:31] [provider.go:55] Performing OIDC Discovery...
[2025/03/23 21:42:31] [proxy.go:77] mapping path "/" => static response 200
[2025/03/23 21:42:31] [oauthproxy.go:172] OAuthProxy configured for OpenID Connect Client ID: bot-idp
[2025/03/23 21:42:31] [oauthproxy.go:178] Cookie settings: name:_oauth2_proxy secure(https):false httponly:true expiry:168h0m0s domains:.localtest.me path:/ samesite: refresh:disabled
and navigate to http://oauth2-proxy.localtest.me:4180/
Run Skipper using example config:
head -c 32 /dev/urandom | base64 > /tmp/secret.txt
go run github.com/zalando/skipper/cmd/skipper@latest -config-file=./doc/skipper.yaml
...
[APP]INFO[0000] Listen on :9090
...
and navigate to http://skipper.localtest.me:9090/
Note
This example uses routes generated from Anubis botPolicies.json
via anubis2eskip tool.
See Skipper documentation for configuration details.