{"id":42358297,"url":"https://github.com/fluffy-bunny/oidc-orchestrator","last_synced_at":"2026-01-27T16:37:35.134Z","repository":{"id":211354216,"uuid":"727979686","full_name":"fluffy-bunny/oidc-orchestrator","owner":"fluffy-bunny","description":null,"archived":false,"fork":false,"pushed_at":"2025-05-06T16:46:37.000Z","size":205,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-05-06T17:42:34.994Z","etag":null,"topics":["azuread","google-identity","idp","oidc","token-exchange"],"latest_commit_sha":null,"homepage":"","language":"CSS","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/fluffy-bunny.png","metadata":{"files":{"readme":"README.md","changelog":null,"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,"zenodo":null}},"created_at":"2023-12-06T01:10:42.000Z","updated_at":"2025-05-06T16:46:40.000Z","dependencies_parsed_at":null,"dependency_job_id":"cc966db5-ed3b-4238-ba21-50fff48d4479","html_url":"https://github.com/fluffy-bunny/oidc-orchestrator","commit_stats":null,"previous_names":["fluffy-bunny/oidc-orchestrator"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/fluffy-bunny/oidc-orchestrator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fluffy-bunny%2Foidc-orchestrator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fluffy-bunny%2Foidc-orchestrator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fluffy-bunny%2Foidc-orchestrator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fluffy-bunny%2Foidc-orchestrator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fluffy-bunny","download_url":"https://codeload.github.com/fluffy-bunny/oidc-orchestrator/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fluffy-bunny%2Foidc-orchestrator/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28816563,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-27T12:25:15.069Z","status":"ssl_error","status_checked_at":"2026-01-27T12:25:05.297Z","response_time":168,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["azuread","google-identity","idp","oidc","token-exchange"],"created_at":"2026-01-27T16:37:35.063Z","updated_at":"2026-01-27T16:37:35.128Z","avatar_url":"https://github.com/fluffy-bunny.png","language":"CSS","funding_links":[],"categories":[],"sub_categories":[],"readme":"# OIDC Orchestrator\n\nThis is an oidc orchestrator that sits in front of a real IDP like azure EntraID (formerly AzureAD), OKTA, Auth0, etc.\n\nWhy in hell would I do this?  \n\nWhen you buy someones app and they claim \"We support SSO integration\", DO NOT BELIEVE THEM.  Its usually such a simplistic integration that it basically useless.  \n\nMature client apps will let you do a [token exchange](https://oauth.net/2/token-exchange/) right after the SSO Login where the id_token is exchanged for an access_token that contains all the necessary claims for downstream api calls.  This is the way it should be done.   So, this orchestrator will take the id_token and exchange it for an access_token that contains all the necessary claims for downstream api calls.\n\nIn this example I am orchestrating google.  In the end the client app doesn't get google id_tokens or access_tokens.  Those are exchanged in the OAuth2 CODE flow for newly minted access_tokens that contain the necessary claims for downstream api calls.  If you have an internal OAuth2 service that supports token exchange, like I do, you would make a call to that by passing google id_token and get back a new access_token and optionally a refresh_token.\n\nSo if your apps SSO integration is pointing to AzureAD, and we all know that the access_tokens we get from Azure are useless.  We can then point the app to our orchestrator that will produce the right tokens.  \n\n## OAuth2 Code Flow\n\n```mermaid\nsequenceDiagram\n    participant ClientApp\n    participant Orchestrator as Orchestrator\u003cbr/\u003e(Authority)\n    participant IDP as IDP\u003cbr/\u003e(Azure EntraID)\n    participant TokenExchange\n\n    ClientApp-\u003e\u003eOrchestrator: GET /.well-known/openid-configuration\n    Orchestrator-\u003e\u003eIDP: GET /.well-known/openid-configuration\n    IDP--\u003e\u003eOrchestrator: Discovery Document\n    Orchestrator-\u003e\u003eOrchestrator: modify discovery document\n    Orchestrator--\u003e\u003eClientApp: Discovery Document\n    ClientApp-\u003e\u003eIDP: redirect /authorize\n    IDP-\u003e\u003eClientApp: redirect /callback\n    ClientApp-\u003e\u003eOrchestrator: POST /token (code)\n    Orchestrator-\u003e\u003eIDP: POST /token (code)\n    activate IDP\n    IDP--\u003e\u003eOrchestrator: TokenResponse\n    deactivate  IDP\n    Orchestrator-\u003e\u003eTokenExchange: /exchange (id_token)\n    activate TokenExchange\n    TokenExchange--\u003e\u003eOrchestrator: token(s)\n    deactivate  TokenExchange\n    Orchestrator--\u003e\u003eClientApp: TokenResponse\n```\n\n## OAuth2 refresh_token flow\n\n```mermaid\nsequenceDiagram\n    participant ClientApp\n    participant Orchestrator as Orchestrator\u003cbr/\u003e(Authority)\n    participant IDP as IDP\u003cbr/\u003e(Azure EntraID)\n \n    ClientApp-\u003e\u003eOrchestrator: POST /oauth2/token  refresh_token\n    note right of Orchestrator: refresh_token has the downstream refresh_token and orchestrator hints encoded.\n    Orchestrator-\u003e\u003eOrchestrator: decode refresh_token\n    Orchestrator-\u003e\u003eIDP: POST /oauth2/token  downstream.refresh_token\n    IDP--\u003e\u003eOrchestrator: response\n    Orchestrator-\u003e\u003eOrchestrator: mint new access_token\n    Orchestrator-\u003e\u003eOrchestrator: mint new refresh_token(downstream.refresh_token + hints)\n    Orchestrator-\u003e\u003eOrchestrator: Build response (orchestrator.refresh_token, orchestrator.access_token, etc)\n\n    Orchestrator--\u003e\u003eClientApp: refresh_token response\n```\n\n## Swagger\n\n[swag](https://github.com/swaggo/swag)  \n\n```bash\ncd cmd/server\nswag init --dir .,../../internal\n```\n\nThis will generate a docs.go file in the cmd/server folder.\n\n## Downstream Services\n\n[google](https://console.cloud.google.com/apis/credentials/oauthclient)  \n\n## Launch Server\n\n### Google Orchestrator\n\n```powershell\ncd cmd/server\ngo build .\n\n$env:PORT = \"9044\";$env:DOWN_STREAM_AUTHORITY = \"https://accounts.google.com\"; .\\server.exe\n```\n\n### Azure EntraID (Azure AD) Orchestrator\n\n```powershell\ncd cmd/server\ngo build .\n\n$env:PORT = \"9044\";$env:DOWN_STREAM_AUTHORITY = \"https://login.microsoftonline.com/f3c3e0c3-ea9e-469c-aca8-3276a8b12d26/v2.0\"; .\\server.exe\n```\n\n## Launch Client App\n\n### Google Client\n\n```powershell\ncd cmd/clientapp\ngo build .\n\n$env:PORT = \"5556\";$env:OAUTH2_CLIENT_ID = \"1096301616546-edbl612881t7rkpljp3qa3juminskulo.apps.googleusercontent.com\";$env:OAUTH2_CLIENT_SECRET = \"**REDACTED**\";$env:AUTHORITY = \"http://localhost:9044\"; .\\clientapp.exe\n```\n\n### Azure EntraID (Azure AD) Client\n\n```powershell\ncd cmd/clientapp\ngo build .\n\n$env:PORT = \"5556\";$env:OAUTH2_CLIENT_ID = \"fe794e91-40ef-430e-9aa5-29e3ca962928\";$env:OAUTH2_CLIENT_SECRET = \"**REDACTED**\";$env:AUTHORITY = \"http://localhost:9044\"; .\\clientapp.exe\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffluffy-bunny%2Foidc-orchestrator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffluffy-bunny%2Foidc-orchestrator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffluffy-bunny%2Foidc-orchestrator/lists"}