Merge commit from fork

* fix: block Login V2 auth for users in deactivated organizations

Enforce organization state on session creation, OIDC token issuance/refresh,
and SAML session creation so deactivated org users cannot authenticate.

Co-authored-by: Cursor <[email protected]>

* fix: reject claim serving for users in deactivated organizations

Require an active resource-owner org in OIDC userinfo and SAML attribute
paths, and use distinct error IDs for inactive user vs inactive org at
token issuance.

Co-authored-by: Cursor <[email protected]>

* fix: drop sessions and tokens when an organization is deactivated

Mirror OrgRemoved cleanup for OrgDeactivated in the V2 session projection
and V1 auth user_session, token, and refresh_token handlers. Also delete
V2 sessions on OrgRemoved, which does not emit per-user removal events.

Co-authored-by: Cursor <[email protected]>

* fix: reject API tokens from deactivated organizations

Check the caller's resource-owner org state in authz middleware via a
cached OrgByID lookup, so already-issued tokens lose ZITADEL API access
when their organization is deactivated. Return unauthenticated (401).
Target org remains unrestricted so instance admins can still manage
deactivated orgs.

Co-authored-by: Cursor <[email protected]>

* fix: invalidate OIDC refresh tokens after org deactivation

Reject refresh exchange if the user's organization was deactivated
after the refresh token was issued, so grants stay dead after reactivate.

Co-authored-by: Cursor <[email protected]>

* fix: invalidate V2 access tokens after org deactivation

Treat OrgDeactivated after the token position as session termination in
ActiveAccessTokenByToken, so issued ATs stay dead after reactivation.

Co-authored-by: Cursor <[email protected]>

---------

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Livio Spring
2026-08-14 06:12:45 +02:00
committed by GitHub
co-authored by Cursor
parent a4266fa7fc
commit 260446f91f
52 changed files with 854 additions and 20 deletions
+3
View File
@@ -35,6 +35,7 @@ type OIDCSessionWriteModel struct {
RefreshToken string
RefreshTokenExpiration time.Time
RefreshTokenIdleExpiration time.Time
RefreshTokenIssuedAt time.Time
aggregate *eventstore.Aggregate
}
@@ -125,6 +126,7 @@ func (wm *OIDCSessionWriteModel) reduceRefreshTokenAdded(e *oidcsession.RefreshT
wm.RefreshTokenID = e.ID
wm.RefreshTokenExpiration = e.CreationDate().Add(e.Lifetime)
wm.RefreshTokenIdleExpiration = e.CreationDate().Add(e.IdleLifetime)
wm.RefreshTokenIssuedAt = e.CreationDate()
}
func (wm *OIDCSessionWriteModel) reduceRefreshTokenRenewed(e *oidcsession.RefreshTokenRenewedEvent) {
@@ -136,6 +138,7 @@ func (wm *OIDCSessionWriteModel) reduceRefreshTokenRevoked(e *oidcsession.Refres
wm.RefreshTokenID = ""
wm.RefreshTokenExpiration = e.CreationDate()
wm.RefreshTokenIdleExpiration = e.CreationDate()
wm.RefreshTokenIssuedAt = time.Time{}
wm.AccessTokenID = ""
wm.AccessTokenExpiration = e.CreationDate()
}