diff --git a/config/crd/bases/iam/iam.miloapis.com_users.yaml b/config/crd/bases/iam/iam.miloapis.com_users.yaml index e548140f..f7794447 100644 --- a/config/crd/bases/iam/iam.miloapis.com_users.yaml +++ b/config/crd/bases/iam/iam.miloapis.com_users.yaml @@ -146,6 +146,16 @@ spec: - type type: object type: array + lastLoginPerProvider: + additionalProperties: + type: string + description: |- + LastLoginPerProvider tracks the most recent login timestamp for each identity provider + that the user has used to authenticate. The map key is the provider name (e.g., "github", "google") + and the value is the RFC3339 timestamp of the last successful login via that provider. + This field is updated by the auth provider when processing idpintent.succeeded events. + Note: This event is only triggered during actual IDP login, not on token refresh. + type: object lastLoginProvider: allOf: - enum: @@ -159,6 +169,14 @@ spec: user to log in (e.g., "github" or "google"). This field is set by the auth provider based on authentication events. type: string + lastTokenIntrospection: + description: |- + LastTokenIntrospection records the timestamp of the most recent successful token introspection + for this user. This is updated during authentication webhook calls when validating access tokens, + which occurs more frequently than actual IDP logins (including token refreshes). + The value is an RFC3339 timestamp. + format: date-time + type: string registrationApproval: description: |- RegistrationApproval represents the administrator’s decision on the user’s registration request. diff --git a/docs/api/iam.md b/docs/api/iam.md index 1ee17986..2f3a312f 100644 --- a/docs/api/iam.md +++ b/docs/api/iam.md @@ -3827,6 +3827,17 @@ populated by the auth provider or any service that provides a user avatar URL.Default: [map[lastTransitionTime:1970-01-01T00:00:00Z message:Waiting for control plane to reconcile reason:Unknown status:Unknown type:Ready]]
false + + lastLoginPerProvider + map[string]string + + LastLoginPerProvider tracks the most recent login timestamp for each identity provider +that the user has used to authenticate. The map key is the provider name (e.g., "github", "google") +and the value is the RFC3339 timestamp of the last successful login via that provider. +This field is updated by the auth provider when processing idpintent.succeeded events. +Note: This event is only triggered during actual IDP login, not on token refresh.
+ + false lastLoginProvider string @@ -3836,11 +3847,23 @@ user to log in (e.g., "github" or "google"). This field is set by the auth provi based on authentication events.
false + + lastTokenIntrospection + string + + LastTokenIntrospection records the timestamp of the most recent successful token introspection +for this user. This is updated during authentication webhook calls when validating access tokens, +which occurs more frequently than actual IDP logins (including token refreshes). +The value is an RFC3339 timestamp.
+
+ Format: date-time
+ + false registrationApproval enum - RegistrationApproval represents the administrator’s decision on the user’s registration request. + RegistrationApproval represents the administrator's decision on the user's registration request. States: - Pending: The user is awaiting review by an administrator. - Approved: The user registration has been approved. diff --git a/pkg/apis/iam/v1alpha1/user_types.go b/pkg/apis/iam/v1alpha1/user_types.go index 64825f69..32d2e234 100644 --- a/pkg/apis/iam/v1alpha1/user_types.go +++ b/pkg/apis/iam/v1alpha1/user_types.go @@ -106,6 +106,22 @@ type UserStatus struct { // +kubebuilder:validation:Enum=github;google LastLoginProvider AuthProvider `json:"lastLoginProvider,omitempty"` + // LastLoginPerProvider tracks the most recent login timestamp for each identity provider + // that the user has used to authenticate. The map key is the provider name (e.g., "github", "google") + // and the value is the RFC3339 timestamp of the last successful login via that provider. + // This field is updated by the auth provider when processing idpintent.succeeded events. + // Note: This event is only triggered during actual IDP login, not on token refresh. + // +kubebuilder:validation:Optional + LastLoginPerProvider map[string]string `json:"lastLoginPerProvider,omitempty"` + + // LastTokenIntrospection records the timestamp of the most recent successful token introspection + // for this user. This is updated during authentication webhook calls when validating access tokens, + // which occurs more frequently than actual IDP logins (including token refreshes). + // The value is an RFC3339 timestamp. + // +kubebuilder:validation:Optional + // +kubebuilder:validation:Format=date-time + LastTokenIntrospection *metav1.Time `json:"lastTokenIntrospection,omitempty"` + // AvatarURL points to the avatar image associated with the user. This value is // populated by the auth provider or any service that provides a user avatar URL. // +kubebuilder:validation:Optional diff --git a/pkg/apis/iam/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/iam/v1alpha1/zz_generated.deepcopy.go index 0218d4c2..e99cbfcd 100644 --- a/pkg/apis/iam/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/iam/v1alpha1/zz_generated.deepcopy.go @@ -1596,6 +1596,17 @@ func (in *UserStatus) DeepCopyInto(out *UserStatus) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.LastLoginPerProvider != nil { + in, out := &in.LastLoginPerProvider, &out.LastLoginPerProvider + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.LastTokenIntrospection != nil { + in, out := &in.LastTokenIntrospection, &out.LastTokenIntrospection + *out = (*in).DeepCopy() + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UserStatus.