Skip to content

feat: support nais.io users in tenant APIs - #567

Merged
frodesundby merged 6 commits into
mainfrom
feat/nais-io-user-login
Oct 22, 2026
Merged

frodesundby merged 6 commits into
mainfrom
feat/nais-io-user-login

Conversation

@frodesundby

Copy link
Copy Markdown
Contributor

This pull request introduces support for syncing and authenticating nais.io users via a configurable Zitadel organization. It adds a new ZITADEL_NAIS_ORGANIZATION_ID environment variable (and corresponding Helm value) to enable this feature, updates authentication and JWT validation logic to support dual-organization login, and documents the user lifecycle and permissions. The changes also include integration tests and configuration validation to ensure safe rollout.

Support for nais.io user sync and login:

  • Added new configuration option zitadel.naisOrganizationID (Helm value and environment variable ZITADEL_NAIS_ORGANIZATION_ID) to enable syncing active nais.io users as viewers and allow nais.io login. This is documented in docs/nais_io_users.md. [1] [2] [3] [4]
  • Updated usersync logic to require necessary Zitadel configuration when nais.io sync is enabled and to pass the new organization ID to the usersyncer. [1] [2]

Authentication and JWT validation enhancements:

  • Modified JWT middleware and related configuration to accept tokens from either the tenant organization or the configured nais.io organization, updating validation logic and tests accordingly. [1] [2] [3] [4] [5] [6] [7] [8]
  • Updated OAuth callback logic to use the Zitadel subject (sub) as the authoritative user identity when nais.io login is enabled, preventing cross-organization login by email.

Deployment and configuration:

  • Updated Helm chart (deployment.yaml) to set the new environment variable and adjust OAuth scopes depending on whether nais.io login is enabled. [1] [2]

Testing:

  • Added integration tests to verify that login uses the correct identity source (subject or email) depending on configuration and that only synchronized users can log in.

@frodesundby
frodesundby requested a review from a team as a code owner October 20, 2026 14:03
@frodesundby
frodesundby requested a balanced review from Copilot and removed request for a team October 20, 2026 14:03

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.

🔵 Needs a closer look

Cross-organization identity reconciliation has an unresolved privilege-transfer risk requiring correction and human security review.

1 open issue
1 file not reviewed
What changed in this PR

Adds configurable nais.io user synchronization and authentication to tenant APIs.

Changes:

  • Imports active nais.io users without tenant default roles.
  • Supports dual-organization JWT authentication and subject-based Zitadel login.
  • Adds deployment configuration, lifecycle documentation, and tests.
File Description
internal/​usersync/​usersyncer/​usersyncer.go Integrates the additional user source.
internal/​usersync/​usersyncer/​nais.go Fetches and reconciles nais.io users.
internal/​usersync/​usersyncer/​nais_test.go Tests snapshot fetching and failures.
internal/​usersync/​usersyncer/​nais_integration_test.go Tests lifecycle, permissions, and collisions.
internal/​cmd/​api/​usersync.go Validates and passes sync configuration.
internal/​cmd/​api/​config.go Defines the organization setting.
internal/​cmd/​api/​api.go Passes organization configuration to authentication.
internal/​auth/​middleware/​jwt.go Accepts either configured organization.
internal/​auth/​middleware/​jwt_test.go Tests dual-organization token validation.
internal/​auth/​authn/​handler.go Resolves Zitadel users by subject.
internal/​auth/​authn/​handler_integration_test.go Tests login identity matching.
docs/​nais_io_users.md Documents rollout and user lifecycle.
charts/​nais-api/​values.yaml Adds the optional organization value.
charts/​nais-api/​templates/​deployment.yaml Configures environment and OAuth scopes.
charts/​nais-api/​Feature.yaml Connects the setting to Fasit.

Review effort: Balanced

Comment thread internal/usersync/usersyncer/usersyncer.go Outdated
Google's email fallback could reuse a nais.io user's UUID and grant tenant admin privileges to its existing sessions. Reject email collisions with different external IDs, including identities missing from the current Zitadel snapshot, and cover the reverse collisions with integration tests.
Share user synchronization across sources and retain email-based Console login for both tenant and nais.io users. Document global email uniqueness and defer CLI token changes, preserving the existing tenant JWT authentication.
@frodesundby
frodesundby merged commit 67f2786 into main Oct 22, 2026
10 checks passed
@frodesundby
frodesundby deleted the feat/nais-io-user-login branch October 22, 2026 06:13
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