{"id":13583704,"url":"https://github.com/travisghansen/external-auth-server","last_synced_at":"2025-04-05T13:09:10.699Z","repository":{"id":38840110,"uuid":"181813962","full_name":"travisghansen/external-auth-server","owner":"travisghansen","description":"easy auth for reverse proxies","archived":false,"fork":false,"pushed_at":"2024-03-16T13:17:04.000Z","size":2568,"stargazers_count":331,"open_issues_count":23,"forks_count":44,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-03-29T12:08:43.302Z","etag":null,"topics":["ambassador","authentication","authentication-middleware","envoy","htpasswd","istio","ldap","ldap-authentication","nginx","nginx-ingress","oauth","oauth2","openid","openid-connect","openidconnect-client","reverse-proxy","traefik","traefik-ingress"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/travisghansen.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-04-17T03:57:05.000Z","updated_at":"2025-01-03T21:52:46.000Z","dependencies_parsed_at":"2023-02-13T23:16:27.696Z","dependency_job_id":"44cb5732-88ba-4e3b-81d0-063642793801","html_url":"https://github.com/travisghansen/external-auth-server","commit_stats":null,"previous_names":[],"tags_count":32,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/travisghansen%2Fexternal-auth-server","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/travisghansen%2Fexternal-auth-server/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/travisghansen%2Fexternal-auth-server/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/travisghansen%2Fexternal-auth-server/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/travisghansen","download_url":"https://codeload.github.com/travisghansen/external-auth-server/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247339158,"owners_count":20923014,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ambassador","authentication","authentication-middleware","envoy","htpasswd","istio","ldap","ldap-authentication","nginx","nginx-ingress","oauth","oauth2","openid","openid-connect","openidconnect-client","reverse-proxy","traefik","traefik-ingress"],"created_at":"2024-08-01T15:03:42.741Z","updated_at":"2025-04-05T13:09:10.679Z","avatar_url":"https://github.com/travisghansen.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","others"],"sub_categories":[],"readme":"![Image](https://img.shields.io/docker/pulls/travisghansen/external-auth-server.svg)\n![Image](https://img.shields.io/github/actions/workflow/status/travisghansen/external-auth-server/main.yml?branch=master\u0026style=flat-square)\n\n# `external-auth-server`\n\n`eas` (pronounced `eez`) is primarily focused on lowering the barrier to\nusing various authentication schemes in a kubernetes environment (but it works\nwith any reverse proxy supporting external/forward auth). `eas` can be\ndeployed once and protect many services using disperse authentication methods\nand providers. The goal is to make enabling authentication as easy as:\n\n1. generating a new `config_token` (see below)\n1. configuring the reverse proxy to use the service for external authentication\n1. benefit\n\n# Authentication Plugins\n\nVarious [authentication plugins](PLUGINS.md) are supported. Within a single\n`config_token` you can enable as many as you would like which results in a\npipeline of authentication mechanisms being invoked. The first plugin to result\nin a `2XX` response code will allow the request to be serviced. If **all**\nplugins fail, then by default the result from the final plugin defined in the\n`config_token` will be returned to the client. You can however alter that on\na service-by-service basis by setting the `fallback_plugin=plugin index` (0\nindexed) parameter on the authentication URL.\n\n- htpasswd\n- LDAP\n- OpenID Connect\n- oauth2\n- request param\n- request header\n- request js\n- jwt\n- firebase jwt\n\n# Features\n\n- works with any proxy server (traefik, nginx, ambassador, istio, envoy, etc)\n  that supports forward/external auth\n- works with any `OpenID Connect`/`oauth2` provider (tested predominantly with\n  `keycloak` but it should be agnostic)\n- only requires 1 installation to service any number of\n  providers/configurations/vhosts/domains\n- passes tokens to the backing service via headers\n- automatically refreshes tokens\n- server-side `config_token`s [CONFIG_TOKENS](CONFIG_TOKENS.md)\n\n# Usage\n\nIf running multiple instances (HA) you will need a shared cache/store (see\nredis below). You only **really** need redis if:\n\n1. You are running HA\n1. You are using the `oidc` or `oauth2` plugins\n\nRefer to the [HOWTO](HOWTO.md) for a more detailed overview.\n\n## Prerequisites\n\n### `oauth2` and `oidc`\n\n- `eas` must be able to access `OIDC Provider`\n\n- `user-agent` must be able to access `OIDC Provider`\n- `user-agent` must be able to access `proxy`\n- `user-agent` must be able to access `eas` (if `redirect_uri` is directly\n  pointing to `eas` service `/oauth/callback` endpoint)\n\n- `proxy` must be able to access `eas`\n- `proxy` must send `X-Forwarded-Host` (localhost:8000) to `eas` in sub-request\n- `proxy` must send `X-Forwarded-Uri` (/anything/foo/bar?test=foo) to `eas` in\n  sub-request\n- `proxy` must send `X-Forwarded-Proto` (http) to `eas` in sub-request\n- `proxy` should send `X-Forwarded-Method` (GET) to `eas` in sub-request\n- `proxy` must return non `2XX` responses from `eas` to browser\n- `proxy` may forward `2XX` auth header `X-Id-Token` to backing service\n- `proxy` may forward `2XX` auth header `X-Userinfo` to backing service\n- `proxy` may forward `2XX` auth header `X-Access-Token` to backing service\n- `proxy` may forward `2XX` auth header `Authorization` to backing service\n\n## Launch the server\n\n### source\n\n```\nEAS_CONFIG_TOKEN_SIGN_SECRET=\"foo\" \\\nEAS_CONFIG_TOKEN_ENCRYPT_SECRET=\"bar\" \\\nEAS_ISSUER_SIGN_SECRET=\"super secret\" \\\nEAS_ISSUER_ENCRYPT_SECRET=\"blah\" \\\nEAS_COOKIE_SIGN_SECRET=\"hello world\" \\\nEAS_COOKIE_ENCRYPT_SECRET=\"something\" \\\nEAS_SESSION_ENCRYPT_SECRET=\"baz\" \\\nEAS_CONFIG_TOKEN_STORES='{}' \\\nEAS_LOG_LEVEL=\"info\" \\\nEAS_PORT=8080 \\\nnode src/server.js\n```\n\n### docker\n\n```\ndocker run -d --name eas -p 8080:8080 \\\n-e EAS_CONFIG_TOKEN_SIGN_SECRET=\"foo\" \\\n-e EAS_CONFIG_TOKEN_ENCRYPT_SECRET=\"bar\" \\\n-e EAS_ISSUER_SIGN_SECRET=\"super secret\" \\\n-e EAS_ISSUER_ENCRYPT_SECRET=\"blah\" \\\n-e EAS_COOKIE_SIGN_SECRET=\"hello world\" \\\n-e EAS_COOKIE_ENCRYPT_SECRET=\"something\" \\\n-e EAS_SESSION_ENCRYPT_SECRET=\"baz\" \\\n-e EAS_CONFIG_TOKEN_STORES='{}' \\\n-e EAS_LOG_LEVEL=\"info\" \\\n-e EAS_PORT=8080 \\\ntravisghansen/external-auth-server\n```\n\n### Kubernetes\n\nA `helm` chart is supplied in the repo directly. Reviewing\n[values.yaml](charts/external-auth-server/values.yaml) is **highly**\nrecommended as examples are provided for common use-cases.\n\n```\nhelm repo add eas https://travisghansen.github.io/external-auth-server\nhelm repo update\nhelm upgrade \\\n--install \\\n--namespace=external-auth-server \\\n\\\n--set configTokenSignSecret=\u003crandom\u003e \\\n--set configTokenEncryptSecret=\u003crandom\u003e \\\n--set issuerSignSecret=\u003crandom\u003e \\\n--set issuerEncryptSecret=\u003crandom\u003e \\\n--set cookieSignSecret=\u003crandom\u003e \\\n--set cookieEncryptSecret=\u003crandom\u003e \\\n--set sessionEncryptSecret=\u003crandom\u003e \\\n--set logLevel=\"info\" \\\n\\\n--set redis-ha.enabled=true \\\n--set redis-ha.auth=true \\\n--set redis-ha.redisPassword=53c237 \\\n\\\n--set storeOpts.store=ioredis \\\n--set storeOpts.password=53c237 \\\n--set storeOpts.name=mymaster \\\n--set storeOpts.sentinels[0].host=eas-redis-ha-announce-0 \\\n--set storeOpts.sentinels[0].port=26379 \\\n--set storeOpts.sentinels[1].host=eas-redis-ha-announce-1 \\\n--set storeOpts.sentinels[1].port=26379 \\\n--set storeOpts.sentinels[2].host=eas-redis-ha-announce-2 \\\n--set storeOpts.sentinels[2].port=26379 \\\n--set storeOpts.keyPrefix=\"eas:\" \\\n\\\n--set ingress.enabled=true \\\n--set ingress.hosts[0]=eas.example.com \\\n--set ingress.paths[0]=/ \\\neas eas/external-auth-server\n```\n\n## Generate a token\n\n```\n# please edit the values in bin/generate-config-token.js to your situation\n# ie: issuer disovery URL, client_id, client_secret, etc\n# also make sure to use the same secrets used when launching the server\nEAS_CONFIG_TOKEN_SIGN_SECRET=\"foo\" \\\nEAS_CONFIG_TOKEN_ENCRYPT_SECRET=\"bar\" \\\nnode bin/generate-config-token.js\n\n# alternatively you may use the following to create tokens\n# files can be either json or yaml\ncat config-token.json | docker run --rm -i -e EAS_CONFIG_TOKEN_SIGN_SECRET=foo -e EAS_CONFIG_TOKEN_ENCRYPT_SECRET=bar travisghansen/external-auth-server generate-config-token\ncat config-token.json | EAS_CONFIG_TOKEN_SIGN_SECRET=foo EAS_CONFIG_TOKEN_ENCRYPT_SECRET=bar npm run generate-config-token\n```\n\n## Configure your reverse proxy\n\n```\n# See full examples in the ./examples/ directory\n# particularly nginx has some particular requirements\n# NOTE: run over https in production\n# NOTE: take care to NOT authenticate `eas` with itself (this is particularly\n# possible to happen in service mesh scenarios), whatever tool you use should\n# ensure access to the `eas` service bypasses authentication thereby avoiding\n# recursive behavior\n\n# traefik\naddress = http://\u003ceas server ip\u003e:8080/verify?config_token=\u003ctoken output from above\u003e\n\n# nginx (see examples/nginx.conf)\nproxy_pass \"http://\u003ceas server ip\u003e:8080/verify?redirect_http_code=401\u0026config_token=\u003ctoken output from above\u003e\";\n\n# ingress-nginx (see examples/ingress-nginx.yaml)\n\n# nginx-ingress-controller (see examples/nginx-ingress-controller.yaml)\n\n# traefik ingress\ningress.kubernetes.io/auth-type: forward\ningress.kubernetes.io/auth-url: \"https://eas.example.com/verify?config_token=CONFIG_TOKEN_HERE\"\ningress.kubernetes.io/auth-response-headers: X-Userinfo, X-Id-Token, X-Access-Token, Authorization\n\n# ambassador (see file in examples directory)\n\n# istio (see file in examples directory)\n\n# haproxy-ingress (see file in examples directory)\n\n# contour (see file in examples directory)\n\n# envoy (see file in examples directory)\n\n```\n\n## Endpoints\n\nConfigure the external auth URL to point to the services `/verify`\nendpoint. The URL supports the following query params:\n\n- `config_token=the encrypted configuration token`\n- `redirect_http_code=code` (only use with nginx to overcome external auth\n  module limitations (should be set to `401`), otherwise omitted)\n- `fallback_plugin=plugin index` if all plugins fail authentication which\n  plugin response should be returned to the client\n\nIf your provider does not support wildcards you may expose `eas` directly and\nset the `config_token` `redirect_uri` to the `eas` service at the\n`/oauth/callback` path.\n\n## Additional ENV vars\n\n- `EAS_SSL_CERT` path to ssl cert file to enable https\n- `EAS_SSL_KEY` path to ssl key file to enable https\n- `EAS_GRPC_ADDRESS` the address to start the grpc server on (default is\n  `0.0.0.0`)\n- `EAS_GRPC_PORT` port the grpc server is bound to (default is `50051`)\n- `EAS_GRPC_SSL_CERT` path to ssl cert file to enable https\n- `EAS_GRPC_SSL_KEY` path to ssl key file to enable https\n- `EAS_ALLOW_EVAL` allow for potentially unsafe execution of untrusted code\n  (enables `request_js` and `js` query engine)\n- `EAS_ALLOW_PLAIN_SERVER_SIDE_TOKENS` allows server-side token to be\n  unsigned (ie: store plain json/yaml in the store(s))\n\n## redis\n\n### `ioredis` cache adapter\n\nSupport for sentinel, see `bin/generate-store-opts.js` with further options.\n\n- https://github.com/luin/ioredis/blob/master/API.md#new-redisport-host-options\n\n```\nEAS_STORE_OPTS='{\"store\":\"ioredis\",\"host\":\"localhost\"}'\n```\n\n### `redis` cache adapter\n\nNo support for sentinel currently, see `bin/generate-store-opts.js` with further options.\n\n- https://www.npmjs.com/package/redis#options-object-properties\n\n```\nEAS_STORE_OPTS='{\"store\":\"redis\",\"host\":\"localhost\"}'\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftravisghansen%2Fexternal-auth-server","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftravisghansen%2Fexternal-auth-server","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftravisghansen%2Fexternal-auth-server/lists"}