Skip to content

IS-11630 DevOps Dashboard 2: Backstage app shell with Curity sign-in (M1) - #277

Open
aleixsuau wants to merge 6 commits into
feature/dev/IS-11630-backstage-app-scaffoldfrom
feature/dev/IS-11630-devops-dashboard-backstage
Open

IS-11630 DevOps Dashboard 2: Backstage app shell with Curity sign-in (M1)#277
aleixsuau wants to merge 6 commits into
feature/dev/IS-11630-backstage-app-scaffoldfrom
feature/dev/IS-11630-devops-dashboard-backstage

Conversation

@aleixsuau

@aleixsuau aleixsuau commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Jira: https://curity.atlassian.net/browse/IS-11630

DevOps Dashboard 2 — Curity sign-in for the Backstage app (M1)

Adds Curity authentication to the Backstage host app: users sign in through the local Curity Identity Server, and plugins can obtain an admin-api access token via curityAuthApiRef. This is the seam the DB-clients plugin (M2–M4) builds on.

Stacked PR — based on #278 (the untouched create-app scaffold). This diff is only the hand-written change.

📚 Backstage concepts used here

  • App = two packages. packages/app (React SPA) + packages/backend (Node); they communicate only over HTTP. Shared code needs a third, environment-neutral package (packages/common).
  • Plugins: installable feature packages (frontend, backend, or both) that extend a host app — they ship pages, extensions, utility APIs, and backend routes. This PR only configures the host app; the DB-clients plugin arrives in M2.
  • Utility APIs: an app-wide service registered under an ApiRef (a DI token — here, curityAuthApiRef). Consumers call useApi(ref); other factories can depend on it via deps. Registration happens through extensions bundled in a module (createFrontendModule) and mounted via createApp({ features }).
  • Auth providers are backend-side Backstage modules mounted at /api/auth/<providerId>/*. The frontend uses Backstage's stock OAuth2 client to drive them; the provider id (oidc) links frontend, backend, and the auth.providers.<id> config key — kept in one constant (packages/common).
  • Sign-in page: an extension attached to the app root that gates rendering until the user logs in (SignInPageBlueprint).

🧭 What each side does

Frontend — packages/app/src/modules/auth/

  • curityAuthApi.ts — declares curityAuthApiRef (the DI token plugins use to inject the auth service and call getAccessToken(['urn:se:curity:scopes:admin:api'])) and registers Backstage's OAuth2 client as its implementation, bound to the oidc provider.
  • signInPage.tsx — sign-in gate (auto: silent sign-in when a session exists, button otherwise).
  • authModule.ts / index.ts — module assembly + barrel.

Backend — packages/backend/src/modules/curityOidcAuthProvider.ts

  • Registers the oidc provider using Backstage's stock OIDC authenticator (configured from auth.providers.oidc.development: Curity issuer, client, scopes).
  • Custom sign-in resolver resolves the Backstage identity from the token's sub, without requiring an email claim or a catalog User entity. The testAuth-janedoe authenticator just asserts the username, it needs no password, which makes dev sign-in (and any future automated test) zero-interaction.

Shared — packages/common/

  • CURITY_AUTH_PROVIDER_ID — the provider id used by both sides; app/backend packages must not import each other.

Also: app-config.yaml (provider config + required auth.session.secret), one-line wiring in App.tsx / backend index.ts, and the root start script (see shortcuts below).

🧪 How to test

1. Curity dev server (identity-server repo; runs in the foreground and streams the server/request logs to this terminal — keep it open):

./gradlew packageDebug --parallel
debug/run

2. Register the Backstage OAuth client:

dist/bin/idsh <<'EOF'
configure
set environments environment admin-service http restconf oauth client [ public_client devops_dashboard_backstage ]
set profiles profile oauth-dev oauth-service settings authorization-server client-store config-backed client devops_dashboard_backstage capabilities code
set profiles profile oauth-dev oauth-service settings authorization-server client-store config-backed client devops_dashboard_backstage secret Password1
set profiles profile oauth-dev oauth-service settings authorization-server client-store config-backed client devops_dashboard_backstage redirect-uris http://localhost:7007/api/auth/oidc/handler/frame
set profiles profile oauth-dev oauth-service settings authorization-server client-store config-backed client devops_dashboard_backstage scope openid
set profiles profile oauth-dev oauth-service settings authorization-server client-store config-backed client devops_dashboard_backstage scope profile
set profiles profile oauth-dev oauth-service settings authorization-server client-store config-backed client devops_dashboard_backstage scope email
set profiles profile oauth-dev oauth-service settings authorization-server client-store config-backed client devops_dashboard_backstage scope urn:se:curity:scopes:admin:api
set profiles profile oauth-dev oauth-service settings authorization-server client-store config-backed client devops_dashboard_backstage audience urn:se:curity:audiences:admin:api
set profiles profile oauth-dev oauth-service settings authorization-server client-store config-backed client devops_dashboard_backstage user-authentication allowed-authenticators testAuth-janedoe
commit comment "IS-11630 Register Backstage dev client"
exit
exit
EOF

3. Create the local dev config (from the ui-kit repo root):

git apply src/devops-dashboard-backstage-app/dev-secrets.patch

4. Run the app (ui-kit/src/devops-dashboard-backstage-app):

yarn install && yarn start

Frontend http://localhost:3000, backend :7007.

5. Verify:

  • Opening the app triggers sign-in; the testAuth-janedoe authenticator completes it without a login form.
  • ✅ Catalog renders; Settings → profile shows janedoe.
  • Token check: GET /api/auth/oidc/refresh?... (devtools → Network) returns the session with the admin-api scope granted.

⚠️ Dev-harness shortcuts (intentional, not production)

  • NODE_TLS_REJECT_UNAUTHORIZED=0 in the root start script — the backend fetches the dev server's self-signed OIDC metadata.
  • Dev secrets (client secret, session secret) live in the gitignored app-config.local.yaml, created by dev-secrets.patch; the committed config holds only ${VAR} references.
  • The sub-based resolver signs in any authenticated Curity user without a catalog entity — revisit with the permission model.
  • Browser-held bearer token (MVP ADR); token-handler hardening is a planned follow-up on the epic.

🔭 Next (epic milestones)

M2 Apollo GraphQL foundation → M3 DB-clients list → M4 detail view.

@aleixsuau
aleixsuau changed the base branch from dev to feature/dev/IS-11630-backstage-app-scaffold August 4, 2026 11:58
@aleixsuau
aleixsuau requested review from luisgoncalves, urre and vahag-curity and a lite review from Copilot August 5, 2026 10:49
@aleixsuau
aleixsuau marked this pull request as ready for review August 5, 2026 10:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Curity (OIDC) authentication to the DevOps Dashboard 2 Backstage host app, including a shared provider-id constant for consistent wiring between frontend, backend, and config.

Changes:

  • Introduces a packages/common workspace package to share CURITY_AUTH_PROVIDER_ID across app/backend.
  • Adds a frontend auth module that registers an OAuth2-based curityAuthApiRef and replaces the app root sign-in page.
  • Adds a backend OIDC auth provider module with a custom sub-based sign-in resolver, plus corresponding config/dev-start wiring.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/devops-dashboard-backstage-app/packages/common/src/index.ts Adds shared Curity auth provider id constant.
src/devops-dashboard-backstage-app/packages/common/package.json Defines the new common workspace package.
src/devops-dashboard-backstage-app/packages/backend/src/modules/curityOidcAuthProvider.ts Registers OIDC provider and custom sub-based sign-in resolver.
src/devops-dashboard-backstage-app/packages/backend/src/index.ts Wires the new Curity OIDC backend module into the backend.
src/devops-dashboard-backstage-app/packages/backend/package.json Adds OIDC backend module dependency and workspace dependency on common.
src/devops-dashboard-backstage-app/packages/app/src/modules/auth/signInPage.tsx Adds Curity-gated sign-in page extension.
src/devops-dashboard-backstage-app/packages/app/src/modules/auth/curityAuthApi.ts Adds curityAuthApiRef and registers OAuth2 client implementation.
src/devops-dashboard-backstage-app/packages/app/src/modules/auth/authModule.ts Bundles auth extensions into a frontend module mounted on app.
src/devops-dashboard-backstage-app/packages/app/src/modules/auth/index.ts Barrels exports for the auth module/APIs.
src/devops-dashboard-backstage-app/packages/app/src/App.tsx Mounts the auth module as an app feature.
src/devops-dashboard-backstage-app/packages/app/package.json Adds workspace dependency on common.
src/devops-dashboard-backstage-app/package.json Adjusts start script to run with insecure TLS (dev convenience).
src/devops-dashboard-backstage-app/dev-secrets.patch Adds a patch to generate gitignored local dev secrets config.
src/devops-dashboard-backstage-app/app-config.yaml Adds auth session + OIDC provider configuration.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 8 to 12
"scripts": {
"start": "backstage-cli repo start",
"start": "NODE_TLS_REJECT_UNAUTHORIZED=0 backstage-cli repo start",
"build:backend": "yarn workspace backend build",
"build:all": "backstage-cli repo build --all",
"build-image": "yarn workspace backend build-image",
Comment on lines +6 to +7
"main": "src/index.ts",
"types": "src/index.ts",
clientId: devops_dashboard_backstage
# Dev value comes from the gitignored app-config.local.yaml (see dev-secrets.patch)
clientSecret: ${CURITY_BACKSTAGE_CLIENT_SECRET}
# openid/profile/email are requested by default; add the admin API scope
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants