* fix(auth-backend): harden default allowed patterns for CIMD and DCR
Signed-off-by: benjdlambert <ben@blam.sh>
* address PR review feedback for OIDC defaults
- narrow CLI client ID pattern to exact cli.json path
- add BREAKING prefix to changeset
- add IPv6 [::1] to docs examples
- add loopback redirect URI tests for IPv6 and 127.0.0.1
Signed-off-by: benjdlambert <ben@blam.sh>
* remove dead ['*'] fallback when features are disabled
The restrictive defaults are now always used regardless of the enabled
flag, since the patterns are only consulted on code paths that require
the feature to be enabled.
Signed-off-by: benjdlambert <ben@blam.sh>
* add default pattern tests and fix docs cli example
Signed-off-by: benjdlambert <ben@blam.sh>
* use URL constructor for CLI client ID
Signed-off-by: benjdlambert <ben@blam.sh>
* use string templating for cliClientId to match OidcRouter
Signed-off-by: benjdlambert <ben@blam.sh>
* fix docs: remove misleading CLI client_id URL example
Signed-off-by: benjdlambert <ben@blam.sh>
---------
Signed-off-by: benjdlambert <ben@blam.sh>
Refactors all test files that use TestDatabases/TestCaches with
it.each(databases.eachSupportedId()) to instead use describe.each at
the outer level. This ensures that all tests for one database engine
complete before moving to the next, rather than interleaving engines
across individual tests. This reduces the number of concurrent database
connections and should help with test timeout issues in CI.
The TestDatabases.create() call is hoisted to module scope so the
describe.each can iterate over supported IDs at the top level.
40 files changed across packages/backend-defaults,
packages/backend-test-utils, and multiple plugins.
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
Address review feedback: flip the catalog user existence check to
enabled by default and rename the config option to
`dangerouslyDisableCatalogPresenceCheck` as an escape hatch. Also use
`error.name` instead of `instanceof` for cross-realm error safety.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com>
Add `experimentalRefreshToken.validateCatalogUserExistence` config option
that checks whether the user's catalog entity still exists before issuing
a new access token during refresh. If the user has been removed from the
catalog (e.g. offboarded), the refresh is rejected and the session is
revoked. Transient catalog errors reject the refresh but preserve the
session for retry.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: MT Lewis <mtlewis@users.noreply.github.com>
The uuid package dropped its CommonJS entry point in v14, making it
incompatible with Backstage's CJS build output and Jest test runner.
Rather than working around the ESM-only issue, replace all usage with
the built-in crypto.randomUUID() which has been available in Node.js
since v16.7 and in all major browsers since March 2022.
Signed-off-by: Fredrik Adelöw <freben@spotify.com>
Made-with: Cursor
The function was a thin wrapper around validateCimdUrl that caught errors
and returned a boolean. It was never imported by any production code —
only by test files. Tests now use validateCimdUrl directly.
Made-with: Cursor
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Add a `toError` utility function to `@backstage/errors` that converts
unknown values to `ErrorLike` objects. If the value is already error-like
it is returned as-is. Strings are used directly as the error message, and
other values are stringified with a fallback to JSON.stringify to avoid
unhelpful `[object Object]` messages.
Non-error causes passed to `CustomErrorBase` are now converted and stored
using `toError` rather than discarded. Existing `assertError` call sites
across the codebase are migrated to `toError`.
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
Made-with: Cursor
For CIMD clients using loopback redirect URIs (localhost/127.0.0.1),
match by scheme, hostname, and path only, ignoring the port. Native
CLI apps like Claude Code use ephemeral ports for OAuth callbacks.
Signed-off-by: benjdlambert <ben@blam.sh>
alb-provider: JWT verification block was wrapped in generic error
that turned 401 to 500 causing clients to retry the login
cimd: cimd clients are not registered in oidc_clients table
so inserting offline sessions for them violates the foreign key
constraint. dropping the fk.
offline: return access token even when refresh token issuing fails.
if the refresh token issue fails for some reason, it will return
500 which will then cause client to retry even it can get valid
access token without refresh token.
closes#33329
Signed-off-by: Hellgren Heikki <heikki.hellgren@op.fi>
* fix: prevent SSRF via redirect in CIMD metadata fetch
* fix: prevent SSRF via redirect in CIMD metadata fetch
* fix: add redirect target listener to SSRF redirect test
* 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>