{"id":30808579,"url":"https://github.com/fajarnugraha37/sso","last_synced_at":"2026-05-16T01:32:58.583Z","repository":{"id":310243930,"uuid":"1039196982","full_name":"fajarnugraha37/sso","owner":"fajarnugraha37","description":"This repository is a Docker-based single sign-on sandbox that wires Keycloak, a custom Node.js OIDC provider, and sample services behind an Nginx proxy to demonstrate shared authentication across multiple applications","archived":false,"fork":false,"pushed_at":"2025-08-16T19:02:53.000Z","size":18,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-16T19:22:45.280Z","etag":null,"topics":["authentication","jwt","keycloak","nodejs","oidc","oidc-server","sso"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fajarnugraha37.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2025-08-16T17:27:10.000Z","updated_at":"2025-08-16T19:02:56.000Z","dependencies_parsed_at":"2025-08-16T19:22:51.424Z","dependency_job_id":"55a69073-c6cb-4e33-8f01-29d5618ffb49","html_url":"https://github.com/fajarnugraha37/sso","commit_stats":null,"previous_names":["fajarnugraha37/sso"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/fajarnugraha37/sso","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fajarnugraha37%2Fsso","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fajarnugraha37%2Fsso/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fajarnugraha37%2Fsso/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fajarnugraha37%2Fsso/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fajarnugraha37","download_url":"https://codeload.github.com/fajarnugraha37/sso/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fajarnugraha37%2Fsso/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273854724,"owners_count":25180011,"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","status":"online","status_checked_at":"2025-09-06T02:00:13.247Z","response_time":2576,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["authentication","jwt","keycloak","nodejs","oidc","oidc-server","sso"],"created_at":"2025-09-06T03:48:11.062Z","updated_at":"2026-05-16T01:32:53.564Z","avatar_url":"https://github.com/fajarnugraha37.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SSO Playground\n\nThis repository provides a self-contained single sign-on (SSO) playground built with Docker. It demonstrates how multiple applications can share authentication using [Keycloak](https://www.keycloak.org/) and a custom Node.js OpenID Connect (OIDC) provider.\n\nThe stack consists of two example single-page applications (SPAs), their backend APIs, Keycloak realms, and an OIDC provider that brokers login to Keycloak. Everything is wired together through an Nginx reverse proxy.\n\n## Architecture\n\nAll components run as containers defined in `docker-compose.yml`:\n\n- **Keycloak (internal)** – primary identity provider loaded with the `agency-realm` configuration and a demo user.\n- **Keycloak (external)** – mock external identity provider used for federated login.\n- **ids** – Node.js OIDC provider that federates to the agency Keycloak and mints application tokens for CPDS.\n- **app-1-api** – sample API secured by tokens issued directly by Keycloak.\n- **app-2-api** – sample API secured by tokens from the `ids` provider.\n- **web** – Nginx serving the SPAs and routing API requests to the proper services.\n\n### How It Works\n\n```\n  Client Browser\n        |\n        v\n  +-------------+\n  |     web     |  (Nginx reverse proxy)\n  +------+------+\n         |                      \n         +--------------------------------------+\n         |                                      |\n         v                                      v\n    +----------+                           +----------+\n    | App-1 SPA|                           | App-2 SPA|\n    +-----+----+                           +----+-----+\n          |                                      |\n          v                                      v\n    +----------+                           +----------+\n    |app-1-api |                           |app-2-api |\n    +-----+----+                           +----+-----+\n          |                                      |\n          v                                      v\n    +----------+         federated login    +---------+\n    | Keycloak | \u003c--------------------------|   IDS   |\n    | (agency) |                            +----+----+\n    +-----+----+                                 |\n          |                                      v\n          |                                +-----------+\n          |                                | Keycloak  |\n          |                                | (mock IdP)|\n          |                                +-----------+\n          +------------------------------------+\n               direct tokens for App-1\n```\n\n#### Cross-App SSO Flow\n\nWhen a user already authenticated in **App-1** opens **App-2**, the existing Keycloak\nsession is reused so no extra login is required:\n\n```\nClient Browser\n    |\n    v\n+-----------+\n| App-2 SPA |\n+-----+-----+\n      |\n      | (1) redirect to IDS if no App-2 token\n      v\n+-----------+\n|    IDS    |\n+-----+-----+\n      |\n      | (2) redirect to Keycloak if no IDS session\n      v\n+-----------+\n| Keycloak  |\n+-----+-----+\n      |\n      | (3) existing session -\u003e issue auth code\n      v\n+-----------+\n|    IDS    |\n+-----+-----+\n      |\n      | (4) mint App-2 token \u0026 set cookie\n      v\n+-----------+\n| App-2 SPA |\n+-----+-----+\n      |\n      | (5) call App-2 API with token\n      v\n+-----------+\n| App-2 API |\n+-----------+\n```\n\nThis flow shows how the IDS provider leverages the Keycloak session established with\nApp-1, enabling seamless navigation between apps without a second login.\n\nSee the compose file for exact settings and ports.\n\n## Prerequisites\n\n- [Docker](https://docs.docker.com/get-docker/) and Docker Compose\n- [Make](https://www.gnu.org/software/make/) (optional, used for convenience commands)\n- A host entry for `eservice.localhost` pointing to `127.0.0.1` (add to `/etc/hosts` or similar)\n\n## Getting Started\n\n1. **Start the stack**\n\n   ```bash\n   make up\n   ```\n\n   This builds all images and starts the containers in the background.\n\n2. **Access the apps**\n\n   - App-1 SPA: [Link](http://eservice.localhost/aceas/)\n   - App-2 SPA: [Link](http://eservice.localhost/cpds/)\n\n3. **Default credentials**\n\n   - Keycloak demo user: `demo` / `demo123`\n   - Mock IdP user: `idpuser` / `idp123`\n\n4. **Stop the stack**\n\n   ```bash\n   make down\n   ```\n\n## Service Overview\n\n| Service      | Description |\n|--------------|-------------|\n| `keycloak`   | Keycloak server hosting the `agency-realm` and backing App-2 and App-1 |\n| `keycloak_idp` | Secondary Keycloak instance acting as a mock external identity provider |\n| `ids`        | Node.js OIDC provider that brokers to `keycloak` and issues tokens for App-2 |\n| `app-1-api`  | Example API protected by Keycloak-issued tokens |\n| `app-2-api`   | Example API protected by tokens from the `ids` provider |\n| `web`        | Nginx reverse proxy serving static SPAs and routing requests |\n\n## Useful Make Targets\n\n- `make up` – build and start all containers\n- `make down` – stop and remove containers and images\n- `make re-ids` / `make re-cpds` / `make re-aceas` – rebuild a specific service\n- `make log-ids` (and similar) – follow logs for a service\n\n## Directory Structure\n\n```\n.\n├─ keycloak/         # Realm exports and mock IdP configuration\n├─ services/         # Node.js services (ids, app-2-api, app-1-api)\n├─ webroot/          # Static SPA frontends\n├─ nginx.conf        # Reverse proxy configuration\n├─ docker-compose.yml\n└─ Makefile\n```\n\n## Notes\n\n- The SPAs assume the site is served from `http://eservice.localhost`. Ensure your hosts file maps this name to `127.0.0.1`.\n- The `ids` service demonstrates exchanging Keycloak tokens for application-specific tokens and includes endpoints for login, refresh and logout.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffajarnugraha37%2Fsso","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffajarnugraha37%2Fsso","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffajarnugraha37%2Fsso/lists"}