feat(identity): add read-only Passkey kind and passkey/email login providers - #727
Conversation
There was a problem hiding this comment.
is this file necessary?
There was a problem hiding this comment.
Removed. You're right — none of the other provider flags have a registration test, so this file didn't add value.
Re-applies the io.k8s.* OpenAPI model-name rename from f69bba9 (k8s 1.35.0 compatibility) on top of the openapi-gen v0.23.0 output, which still emits Go-import-path model names and would crash the apiserver at startup ("cannot find model definition for k8s.io/apimachinery/pkg/apis/meta/v1.Time").
79b4387 to
caa1228
Compare
|
@yahyafakhroji could you validate this works correctly in staging before we merge it into main? |
|
We should try testing this in a local environment so we can confirm the whole experience works end-to-end. We shouldn't need to use staging for this kind of testing. |
|
@scotwells @JoseSzycho about the staging question — I haven't tested this on staging, because right now it can't really run there. The feature is behind a gate that's off by default, so even if we deploy this PR, nothing changes yet. Also, the passkey data comes from zitadel-provider, and that part can only be built after this PR is merged and released. So the order is: merge this → release → build the provider side → then turn it on in staging. What I tested so far (agree with Scot — this was all in the local environment):
One small thing I found while testing: if the gate is on but the provider URL is not set, listing passkeys throws an error. Sessions and useridentities already behave the same way today, so it's not from this PR. I'll create a follow-up to give all three a proper error message. Once the zitadel-provider side is ready, we can do the full end-to-end check (actual passkeys showing up in the portal) — locally first, then staging as the final check. |
|
@yahyafakhroji we should be able to put all components (zitdel-provider, zitadel, milo, auth-ui, etc) all into a single local development environment and prove that everything works end-to-end before we merge any changes. |
JoseSzycho
left a comment
There was a problem hiding this comment.
Everything looks ok. The dynamic and rest code matches the exact pattern we use with the other identities.
The API follows the same naming conventions and code is correctly formatted and code is generated.
Good work.
Do not forget to enable the feature-gate from the infra repo
Summary
Phase A groundwork for datum-cloud/enhancements#738 (passkey support — management + login first, email+passkey signup second, per the discussion on the issue):
LastLoginProviderenum: addspasskeyandemailto the allowed values onUserStatusso status writes don't get rejected by validation once passkey logins happen.Passkeyvirtual kind (identity.miloapis.com/v1alpha1): list/get only, served by the aggregated apiserver and backed by the auth provider via a new--passkeys-provider-urlflag, following theUserIdentity/Sessionpattern (REST storage, DynamicProvider, StorageProvider wiring). The cloud portal will use it for a display-only passkeys card.Everything is behind a new alpha feature gate (default off) — zero runtime change until the gate is enabled.
Design notes for reviewers
Lister/Getteronly (noGracefulDeleter/Creater/Updater). Passkey mutations (enroll/remove) live in auth-ui behind step-up re-auth, mirroring how SSO account linking works today.status.userUID+ field selector: registered exactly likeSession/UserIdentityso self-scoped list works viaX-Remote-Uidand cross-user reads go through the existing SAR path (staff support views).metadata.name= Zitadel passkey ID;status.displayName;status.state: Active|Inactive.docs/api/iam.md) are all regenerated —task generateproduces no diff on this branch.Testing
go build ./...clean; 12 new/updated tests across 7 packages, all passing (enum CRD validation, deepcopy independence, field-selector parity, REST list/get behavior, provider wiring, feature gate).Test plan
task dev:redeploy→task kubectl -- get passkeys(expect clean empty list)