feat(cli): add auth commands for OIDC login (#32920)

* feat(cli): add auth commands for OIDC login

Signed-off-by: benjdlambert <ben@blam.sh>

* address PR review feedback

- move CIMD check before callback server start
- add try/finally for callback server cleanup
- validate URLs with human-readable errors
- deduplicate config URL candidates
- preserve selected flag on re-authentication
- delete accessToken on logout
- log token refresh to stderr in show command
- fix command descriptions to reference CIMD not DCR
- type keytar as optionalDependency, rename storage paths
- add auth-backend changeset

Signed-off-by: benjdlambert <ben@blam.sh>

* migrate auth module from yargs to cleye pattern

Signed-off-by: benjdlambert <ben@blam.sh>

* address PR review feedback

- consolidate storage imports in auth.ts
- add withMetadataLock to setSelectedInstance
- skip file permission tests on Windows
- clarify changeset endpoint path

Signed-off-by: benjdlambert <ben@blam.sh>

* address review feedback from Rugvip and Copilot

- use stdout for user-facing messages instead of stderr
- remove clientSecret remnants from logout
- make refresh_token optional in token response schema
- add timeout to CIMD metadata fetch
- pass same state to callback server and authorize URL
- remove inaccurate test comment

Signed-off-by: benjdlambert <ben@blam.sh>

* validate state in callback server, add CIMD endpoint tests

- localServer now validates the OAuth state parameter in the request
  handler and returns 400 on mismatch
- Added tests for the CIMD metadata endpoint in OidcRouter covering
  both disabled and enabled cases

Signed-off-by: benjdlambert <ben@blam.sh>

* revert validateRequest to use Zod error details

Signed-off-by: benjdlambert <ben@blam.sh>

* fix callback server hanging by closing keep-alive connections

Signed-off-by: benjdlambert <ben@blam.sh>

* rename secret store service prefix to backstage-cli:auth-instance

Signed-off-by: benjdlambert <ben@blam.sh>

---------

Signed-off-by: benjdlambert <ben@blam.sh>
This commit is contained in:
Ben Lambert
2026-03-10 14:28:25 +01:00
committed by GitHub
parent d056002e64
commit d0f4cd215b
29 changed files with 3314 additions and 1 deletions
+43 -1
View File
@@ -3329,6 +3329,7 @@ __metadata:
"@types/jest": "npm:^30.0.0"
"@types/node": "npm:^22.13.14"
"@types/npm-packlist": "npm:^3.0.0"
"@types/proper-lockfile": "npm:^4"
"@types/recursive-readdir": "npm:^2.2.0"
"@types/rollup-plugin-peer-deps-external": "npm:^2.2.0"
"@types/rollup-plugin-postcss": "npm:^3.1.4"
@@ -3379,6 +3380,7 @@ __metadata:
jest-css-modules: "npm:^2.1.0"
jsdom: "npm:^27.1.0"
json-schema: "npm:^0.4.0"
keytar: "npm:^7.9.0"
lodash: "npm:^4.17.21"
mini-css-extract-plugin: "npm:^2.4.2"
minimatch: "npm:^10.2.1"
@@ -3392,6 +3394,7 @@ __metadata:
postcss: "npm:^8.1.0"
postcss-import: "npm:^16.1.0"
process: "npm:^0.11.10"
proper-lockfile: "npm:^4.1.2"
raw-loader: "npm:^4.0.2"
react-dev-utils: "npm:^12.0.0-next.60"
react-refresh: "npm:^0.17.0"
@@ -3435,6 +3438,9 @@ __metadata:
terser-webpack-plugin: ^5.1.3
webpack: ~5.105.0
webpack-dev-server: ^5.0.0
dependenciesMeta:
keytar:
optional: true
peerDependenciesMeta:
"@jest/environment-jsdom-abstract":
optional: true
@@ -22784,6 +22790,15 @@ __metadata:
languageName: node
linkType: hard
"@types/proper-lockfile@npm:^4":
version: 4.1.4
resolution: "@types/proper-lockfile@npm:4.1.4"
dependencies:
"@types/retry": "npm:*"
checksum: 10/b0d1b8e84a563b2c5f869f7ff7542b1d83dec03d1c9d980847cbb189865f44b4a854673cdde59767e41bcb8c31932e613ac43822d358a6f8eede6b79ccfceb1d
languageName: node
linkType: hard
"@types/protocol-buffers-schema@npm:^3.4.3":
version: 3.4.3
resolution: "@types/protocol-buffers-schema@npm:3.4.3"
@@ -22972,6 +22987,13 @@ __metadata:
languageName: node
linkType: hard
"@types/retry@npm:*":
version: 0.12.5
resolution: "@types/retry@npm:0.12.5"
checksum: 10/3fb6bf91835ca0eb2987567d6977585235a7567f8aeb38b34a8bb7bbee57ac050ed6f04b9998cda29701b8c893f5dfe315869bc54ac17e536c9235637fe351a2
languageName: node
linkType: hard
"@types/retry@npm:0.12.0":
version: 0.12.0
resolution: "@types/retry@npm:0.12.0"
@@ -37674,6 +37696,17 @@ __metadata:
languageName: node
linkType: hard
"keytar@npm:^7.9.0":
version: 7.9.0
resolution: "keytar@npm:7.9.0"
dependencies:
node-addon-api: "npm:^4.3.0"
node-gyp: "npm:latest"
prebuild-install: "npm:^7.0.1"
checksum: 10/904795bc304f8ad89b80f915c869a941a383312b58584212a199473d18647035cfda92a9c53e6c53bf13ea0fed23037c9597eb418a5c71ee9454f140f026fac9
languageName: node
linkType: hard
"keyv@npm:*, keyv@npm:^5.2.1":
version: 5.6.0
resolution: "keyv@npm:5.6.0"
@@ -40726,6 +40759,15 @@ __metadata:
languageName: node
linkType: hard
"node-addon-api@npm:^4.3.0":
version: 4.3.0
resolution: "node-addon-api@npm:4.3.0"
dependencies:
node-gyp: "npm:latest"
checksum: 10/d3b38d16cb9ad0714d965331d0e38cef1c27750c2c3343cd3464a9ed8158501a2910ccbf2fd9fdc476e806a19dbc9e0524ff9d66a7c779d42a9752a63ba30b80
languageName: node
linkType: hard
"node-addon-api@npm:^8.0.0, node-addon-api@npm:^8.2.2, node-addon-api@npm:^8.3.0, node-addon-api@npm:^8.3.1":
version: 8.5.0
resolution: "node-addon-api@npm:8.5.0"
@@ -43605,7 +43647,7 @@ __metadata:
languageName: node
linkType: hard
"prebuild-install@npm:^7.1.1, prebuild-install@npm:^7.1.3":
"prebuild-install@npm:^7.0.1, prebuild-install@npm:^7.1.1, prebuild-install@npm:^7.1.3":
version: 7.1.3
resolution: "prebuild-install@npm:7.1.3"
dependencies: