Authz: Add builtin provisioning access policy (#101000)

This commit is contained in:
Ryan McKinley
2025-02-20 12:17:52 +03:00
committed by GitHub
parent 4dfb21ecdd
commit c654a580f7
+37 -2
View File
@@ -31,6 +31,7 @@ func checkNilRequester(r Requester) bool {
}
const serviceName = "service"
const serviceNameForProvisioning = "provisioning"
// WithServiceIdentity sets an identity representing the service itself in provided org and store it in context.
// This is useful for background tasks that has to communicate with unfied storage. It also returns a Requester with
@@ -53,6 +54,30 @@ func WithServiceIdentity(ctx context.Context, orgID int64) (context.Context, Req
return WithRequester(ctx, r), r
}
func WithProvisioningIdentitiy(ctx context.Context, namespace string) (context.Context, Requester, error) {
ns, err := types.ParseNamespace(namespace)
if err != nil {
return nil, nil, err
}
r := &StaticRequester{
Type: types.TypeAccessPolicy,
Name: serviceNameForProvisioning,
UserUID: serviceNameForProvisioning,
AuthID: serviceNameForProvisioning,
Login: serviceNameForProvisioning,
OrgRole: RoleAdmin,
IsGrafanaAdmin: true,
Namespace: namespace,
OrgID: ns.OrgID,
Permissions: map[int64]map[string][]string{
ns.OrgID: serviceIdentityPermissions,
},
}
return WithRequester(ctx, r), r, nil
}
// WithServiceIdentityContext sets an identity representing the service itself in context.
func WithServiceIdentityContext(ctx context.Context, orgID int64) context.Context {
ctx, _ = WithServiceIdentity(ctx, orgID)
@@ -79,19 +104,29 @@ var serviceIdentityPermissions = getWildcardPermissions(
"folders:read",
"folders:write",
"folders:create",
"folders:delete",
"dashboards:read",
"dashboards:write",
"dashboards:create",
"datasources:query",
"datasources:read",
"datasources:delete",
"alert.provisioning:write",
"alert.provisioning.secrets:read",
"users:read", // accesscontrol.ActionUsersRead,
"org.users:read", // accesscontrol.ActionOrgUsersRead,
"teams:read", // accesscontrol.ActionTeamsRead,
)
func IsServiceIdentity(ctx context.Context) bool {
ident, err := GetRequester(ctx)
ident, ok := types.AuthInfoFrom(ctx)
if !ok {
return false
}
t, uid, err := types.ParseTypeID(ident.GetUID())
if err != nil {
return false
}
return ident.GetUID() == types.NewTypeID(types.TypeAccessPolicy, serviceName)
return t == types.TypeAccessPolicy && (uid == serviceName || uid == serviceNameForProvisioning)
}