Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/adr-0024-sso-nav.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@objectstack/plugin-auth': patch
---

Auth: surface "SSO Providers" in the Setup app nav when SSO is enabled (ADR-0024 / cloud#551)

The `sys_sso_provider` admin object (register / list / delete external OIDC IdPs) had no navigation entry, so an admin could only reach it by direct URL. `AuthPlugin` now contributes an **"SSO Providers"** entry into the Setup app's **Access Control** group — but only when the external-IdP RP is wired (`AuthManager.isSsoWired()`, which captures both self-host `OS_SSO_ENABLED` and the cloud per-env `planAllowsSso` arriving via `plugins.sso`). Owning-plugin-contributes pattern (ADR-0029 K2), mirroring `plugin-security`. `isSsoWired()` is made public for this gate.
5 changes: 4 additions & 1 deletion packages/plugins/plugin-auth/src/auth-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1970,8 +1970,11 @@ export class AuthManager {
* in `buildPlugins()` (`ssoFromEnv ?? pluginConfig.sso ?? false`) so the
* advertised capability can never disagree with the actual `/sign-in/sso`
* route. `OS_SSO_ENABLED` (when set) wins over the config-file setting.
* Public so `AuthPlugin` can gate the Setup-nav "SSO Providers" entry on it
* (captures both self-host `OS_SSO_ENABLED` and the cloud per-env
* `planAllowsSso` config, since that arrives via `plugins.sso`).
*/
private isSsoWired(): boolean {
public isSsoWired(): boolean {
const ssoEnv = (globalThis as any)?.process?.env?.OS_SSO_ENABLED;
const ssoFromEnv = ssoEnv != null ? String(ssoEnv).toLowerCase() === 'true' : undefined;
return ssoFromEnv ?? (this.config.plugins as any)?.sso ?? false;
Expand Down
28 changes: 28 additions & 0 deletions packages/plugins/plugin-auth/src/auth-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,34 @@ export class AuthPlugin implements Plugin {
dashboards: [SystemOverviewDashboard],
// ADR-0021 — datasets backing the System Overview dashboard's widgets.
datasets: SystemOverviewDatasets,
// ADR-0024 / cloud#551 — surface "SSO Providers" (sys_sso_provider) in the
// Setup app's Access Control group, but ONLY when the external-IdP RP is
// wired (self-host `OS_SSO_ENABLED`, or the cloud per-env `planAllowsSso`
// arriving via `plugins.sso`). Without the gate the entry would render an
// empty list + a "Register" button whose endpoint 404s when SSO is off.
// Owning-plugin-contributes pattern (ADR-0029 K2), mirroring plugin-security.
...(this.authManager.isSsoWired()
? {
navigationContributions: [
{
app: 'setup',
group: 'group_access_control',
// After Roles/Permission-Sets (100) and Sharing (200), near API Keys (300).
priority: 250,
items: [
{
id: 'nav_sso_providers',
type: 'object',
label: 'SSO Providers',
objectName: 'sys_sso_provider',
icon: 'log-in',
requiredPermissions: ['manage_platform_settings'],
},
],
},
],
}
: {}),
});

ctx.logger.info('Auth Plugin initialized successfully');
Expand Down