identity

package
v0.2.49 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 6, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

Documentation

Overview

Package identity builds the cross-workspace ServiceAccount identity railgrid authorizes foreign SAs under.

kcp ServiceAccount usernames ("system:serviceaccount:{ns}:{name}") are logical-cluster-scoped — the same string means a DIFFERENT principal in every workspace, so binding RBAC to it in a tenant workspace would also match a same-named SA the tenant created themselves.

kcp already defines the disambiguated form: the GlobalServiceAccount feature gate (beta, default-on since kube 1.35 in the kcp fork) makes kcp's RBAC resolution alias every SA to

system:kcp:serviceaccount:{cluster}:{ns}:{name}

(see EffectiveUsers in the fork's pkg/registry/rbac/validation/kcp.go and kcp's e2e TestAPIResourceSchemaVirtualWorkspaceAuthorization, which binds exactly this subject across workspaces). Railgrid emits the same format — after verifying the home cluster via TokenReview — so the grant objects created on tenant Enable use kcp-native subjects: the same binding that satisfies railgrid's delegated SAR also authorizes the SA on kcp-native paths.

Both sides — the SAR caller in pkg/virtual/builder and the grant writer in pkg/hub/kcp — MUST use these helpers so the encodings cannot drift.

Index

Constants

View Source
const (
	// LabelSubject holds the hash of the identity a User was created with
	// (OIDCSubjectHash, or StaticToken.Sub). It is the User's primary IdP
	// binding and never changes once set.
	LabelSubject = "tenants.railgrid.ai/sub"

	// LinkedIdentityLabelPrefix prefixes one label per additional OIDC
	// identity linked to a User after creation: the key is the prefix plus
	// the identity's OIDCSubjectHash, the value is always "true". A User can
	// carry any number of them, so one account survives a change of IdP
	// connector (Dex's sub is connector-scoped) or of the IdP itself.
	LinkedIdentityLabelPrefix = "identities.tenants.railgrid.ai/"
)

Variables

This section is empty.

Functions

func EmailLinkable added in v0.2.47

func EmailLinkable(user *tenancyv1alpha1.User, email string) bool

EmailLinkable reports whether a new identity presenting email may be linked onto the User: one of the User's own identities presents that email (case-insensitively) and is not recorded as having it unverified. An entry written before EmailVerified was recorded carries no verdict and is trusted as it always was.

func FindUserByOIDCSubject added in v0.2.47

func FindUserByOIDCSubject(ctx context.Context, client *railgridclient.Client, subjectHash string) (*tenancyv1alpha1.User, error)

FindUserByOIDCSubject returns the User bound to the identity with the given OIDCSubjectHash, as its primary identity or as a linked one, or nil when no User is bound to it.

func HasOIDCIdentity added in v0.2.47

func HasOIDCIdentity(user *tenancyv1alpha1.User) bool

HasOIDCIdentity reports whether the User is bound to any IdP identity, primary or linked.

func IdentityEntry added in v0.2.47

func IdentityEntry(user *tenancyv1alpha1.User, issuer, sub string) *tenancyv1alpha1.OIDCProvider

IdentityEntry returns the User's spec.oidcProviders entry for the identity with the given issuer and subject, or nil. An entry written before the issuer was recorded has none and matches on the subject alone, but only when no entry names the issuer: a Dex that moved hostname keeps its connectors' subjects, so the same subject can be bound under two issuers.

func LinkedIdentityLabel added in v0.2.47

func LinkedIdentityLabel(subjectHash string) string

LinkedIdentityLabel is the label key that links the identity with the given OIDCSubjectHash to a User.

func OIDCSubjectHash added in v0.2.47

func OIDCSubjectHash(issuer, sub string) string

OIDCSubjectHash is the label-safe key of an OIDC identity: the first 63 hex characters (a label value's and a label name's maximum length) of sha256(issuer + "/" + sub).

func QualifiedServiceAccount

func QualifiedServiceAccount(homeCluster, namespace, name string) string

QualifiedServiceAccount builds the global username from parts. Used by the grant writer, which knows the SA's coordinates rather than holding a TokenReview result.

func QualifyServiceAccount

func QualifyServiceAccount(homeCluster, saUsername string) (string, bool)

QualifyServiceAccount converts a TokenReview-resolved ServiceAccount username ("system:serviceaccount:{ns}:{name}") plus its verified home logical cluster into kcp's global form "system:kcp:serviceaccount:{homeCluster}:{ns}:{name}".

Returns false when saUsername is not a ServiceAccount username.

Types

type StaticToken

type StaticToken struct {
	// Sub is the 63-char value stored in the User CR's
	// tenants.railgrid.ai/sub label (a label value's maximum length).
	Sub string
	// UID is the short hash kcp's token-auth file records as the uid.
	UID string
	// RBACIdentity is the kcp username the token authenticates as,
	// "railgrid:static:<uid>". It is also the User's display name.
	RBACIdentity string
	// UserName is the User CR name, "static-user-<uid>".
	UserName string
}

StaticToken is everything railgrid derives from a static bearer token. Every field is a hash of the token, never the token text: the User CR and its email/display name are readable by fellow org members, so anything built from the token itself would hand them a working credential.

The hub proxy (pkg/server/proxy), the embedded kcp token-auth file (pkg/hub/kcp) and the dev setup (pkg/cli/cmd/dev/plugin) MUST all use this so the User CR, the kcp-authenticated username and --admin-users agree.

func NewStaticToken

func NewStaticToken(token string) StaticToken

NewStaticToken derives the identity for a static bearer token.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL