mirror of
https://github.com/Noooste/garage-ui.git
synced 2026-08-31 01:09:25 +00:00
feat(oidc): add fine grained access control (#91)
* feat(access-control): fine grain tokens * fix(docs): clean wording * test(access-control): add tests for team extraction from access tokens and bucket info permissions * test(vocabulary): add test for ExpandGlob function to reject non-glob patterns * feat(helm): add multi-user access control documentation and schema support
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
package authz
|
||||
|
||||
import (
|
||||
"Noooste/garage-ui/internal/auth"
|
||||
)
|
||||
|
||||
// TeamResolver maps an authenticated identity to an authorization Subject.
|
||||
// It is an interface so non-OIDC identity sources (deferred in v1) can plug
|
||||
// in later without touching middleware or handlers.
|
||||
type TeamResolver interface {
|
||||
Resolve(userInfo *auth.UserInfo) Subject
|
||||
}
|
||||
|
||||
type configTeamResolver struct {
|
||||
policy *Policy
|
||||
adminRoles []string
|
||||
}
|
||||
|
||||
// NewTeamResolver builds the v1 resolver: OIDC identities resolve through the
|
||||
// compiled policy; admin/token logins resolve to the synthetic admin subject
|
||||
// (non-OIDC team mapping is deferred).
|
||||
func NewTeamResolver(policy *Policy, adminRoles []string) TeamResolver {
|
||||
return &configTeamResolver{policy: policy, adminRoles: adminRoles}
|
||||
}
|
||||
|
||||
func (r *configTeamResolver) Resolve(userInfo *auth.UserInfo) Subject {
|
||||
id := userInfo.Email
|
||||
if id == "" {
|
||||
id = userInfo.Username
|
||||
}
|
||||
|
||||
// Trust only signed claims, never the transport channel: the auth method
|
||||
// is a JWT claim stamped at login. Legacy sessions ("") resolve like OIDC
|
||||
// so a replayed cookie can never escalate.
|
||||
if userInfo.AuthMethod == "admin" || userInfo.AuthMethod == "token" {
|
||||
return AdminSubject(id)
|
||||
}
|
||||
|
||||
for _, role := range userInfo.Roles {
|
||||
for _, adminRole := range r.adminRoles {
|
||||
if role == adminRole {
|
||||
return AdminSubject(id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
subj := Subject{ID: id, ClusterPerms: PermSet{}}
|
||||
for _, team := range r.policy.TeamsForClaims(userInfo.Teams) {
|
||||
subj.Bindings = append(subj.Bindings, team.Bindings...)
|
||||
for perm := range team.ClusterPerms {
|
||||
subj.ClusterPerms[perm] = struct{}{}
|
||||
}
|
||||
}
|
||||
return subj
|
||||
}
|
||||
Reference in New Issue
Block a user