Repository navigation
feat: support nais.io users in tenant APIs - #567
Merged
Merged
Conversation
frodesundby
requested
a balanced review from Copilot
and removed request for
a team
October 20, 2026 14:03
Contributor
There was a problem hiding this comment.
🔵 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
.env.example: Excluded by your content exclusion settings
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
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

This pull request introduces support for syncing and authenticating nais.io users via a configurable Zitadel organization. It adds a new
ZITADEL_NAIS_ORGANIZATION_IDenvironment 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:
zitadel.naisOrganizationID(Helm value and environment variableZITADEL_NAIS_ORGANIZATION_ID) to enable syncing active nais.io users as viewers and allow nais.io login. This is documented indocs/nais_io_users.md. [1] [2] [3] [4]usersynclogic 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:
sub) as the authoritative user identity when nais.io login is enabled, preventing cross-organization login by email.Deployment and configuration:
deployment.yaml) to set the new environment variable and adjust OAuth scopes depending on whether nais.io login is enabled. [1] [2]Testing: