{"id":28170251,"url":"https://github.com/coreprocess/entra-spa-widgets-poc","last_synced_at":"2025-05-15T17:18:28.605Z","repository":{"id":292636737,"uuid":"981479520","full_name":"coreprocess/entra-spa-widgets-poc","owner":"coreprocess","description":null,"archived":false,"fork":false,"pushed_at":"2025-05-11T08:28:35.000Z","size":346,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-11T09:24:13.055Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/coreprocess.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-05-11T07:47:25.000Z","updated_at":"2025-05-11T08:28:38.000Z","dependencies_parsed_at":"2025-05-11T09:24:19.695Z","dependency_job_id":"c4d484ab-7418-4859-a90b-96b7e529edb5","html_url":"https://github.com/coreprocess/entra-spa-widgets-poc","commit_stats":null,"previous_names":["coreprocess/entra-spa-widgets-poc"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coreprocess%2Fentra-spa-widgets-poc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coreprocess%2Fentra-spa-widgets-poc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coreprocess%2Fentra-spa-widgets-poc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coreprocess%2Fentra-spa-widgets-poc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/coreprocess","download_url":"https://codeload.github.com/coreprocess/entra-spa-widgets-poc/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254384938,"owners_count":22062422,"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":[],"created_at":"2025-05-15T17:18:27.641Z","updated_at":"2025-05-15T17:18:28.595Z","avatar_url":"https://github.com/coreprocess.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🔐 Entra SPA Widgets POC\n\nThis project demonstrates a secure architecture for integrating multiple widget apps (micro frontends) into a central single-page portal app using Azure Entra ID (Microsoft identity platform). Each component is isolated and protected by its own app registration and access token.\n\n![Screenshot](screenshot.png)\n\n---\n\n## 📆 Project Structure\n\n```\n.\n├── portal/\n│   ├── app/         # SPA with MSAL.js login and widget iframes\n│   └── service/     # Express backend protected by Entra access token\n├── widget1/\n│   ├── app/         # Static frontend served via iframe\n│   └── service/     # Token-protected API for Widget1\n├── widget2/\n│   ├── app/         # Static frontend served via iframe\n│   └── service/     # Token-protected API for Widget2\n├── scripts/\n│   └── setup-azure-apps.sh   # Automates Entra app registrations and config\n├── pnpm-workspace.yaml\n└── package.json\n```\n\n---\n\n## ⚙️ Prerequisites\n\n* Node.js + PNPM\n* Azure CLI with access to create AAD app registrations\n* [`jq`](https://stedolan.github.io/jq/) and `uuidgen` installed\n* Developer tenant or test Entra environment\n\n---\n\n## 🚀 Setup\n\n1. **Provision Azure Entra app registrations**:\n\n```bash\naz login\n./scripts/setup-azure-apps.sh\n```\n\nThis will:\n\n* Register 3 apps: Portal, Widget1, Widget2\n* Assign scopes and pre-authorized apps\n* Set `accessTokenAcceptedVersion = 2`\n* Write `config.js` into each frontend/backend folder\n\n2. **Install dependencies and start all apps**:\n\n```bash\npnpm install\npnpm dev\n```\n\nThis will run:\n\n* Portal on `http://localhost:3000`\n* Widget1 on `http://localhost:3001`\n* Widget2 on `http://localhost:3002`\n* Each backend on ports `3100`, `3101`, and `3102` respectively\n\n---\n\n## 🧪 How It Works\n\n* The **portal SPA** logs in the user using `msal-browser` (popup)\n* It obtains access tokens for:\n\n  * Its own API\n  * Widget1 and Widget2 APIs\n* It sends tokens to the widgets using `postMessage`\n* Each widget uses the received token to call its own backend\n* All backends validate the token using `jwks-rsa` and Entra public keys\n\n---\n\n## 🔒 Security Notes\n\n* All access tokens are v2.0 and scoped to the specific app\n* Each API checks the `aud` (audience) and `iss` (issuer) claim\n* Each API also checks the `scp` claim matches the expected scope (e.g. `access_as_user`)\n* CORS is configured to allow only frontend origin access\n* No secrets are used; only public SPA flows\n\n---\n\n## 🚜 Cleanup\n\nTo remove all created Entra apps, manually delete them via Azure Portal. All created Entra apps are prefixed with \"Pre-Auth-App-Test\".\n\n---\n\n## 📎 Related\n\n* [MSAL.js Docs](https://github.com/AzureAD/microsoft-authentication-library-for-js)\n* [Microsoft Identity Platform Overview](https://learn.microsoft.com/en-us/azure/active-directory/develop/)\n* [Entra ID App Manifest Reference](https://learn.microsoft.com/en-us/azure/active-directory/develop/reference-app-manifest)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcoreprocess%2Fentra-spa-widgets-poc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcoreprocess%2Fentra-spa-widgets-poc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcoreprocess%2Fentra-spa-widgets-poc/lists"}