Depends on: Resource Framework
RFCs: RFC-020
Abstract
This spec defines the authorization model of ODF nodes - how accounts, groups, auth attributes, actions, and policies are expressed as resources of the Resource Framework. The model is engine-agnostic: a minimal node can implement simple ownership checks, while a full node can plug in an RBAC / ABAC / ReBAC policy engine, with both remaining interoperable at the level of resources.Terminology
This spec builds on the , , , , and concepts defined in the glossary, and introduces the following terms:- Subject - the party a grant is given to in a policy binding: a principal, a group, or a well-known set of principals
- Group - a named, possibly nested set of subjects that policies can be bound to, so that permissions are granted to all members at once
- Action - an operation the principal attempts to perform, identified by a schema URI (e.g.
View,Read,Decrypt) - Object - the target of an action: a resource, an entity, or a resource type (for actions like
CreateandListwhere no instance exists yet)
Maturity Levels
Implementations may support authorization at one of the following maturity levels:Accounts
Node
An ODF node. Acts as a principal in system tasks and node-to-node communications, and may own a few node-wide resources (e.g. thenode/admins group).
User
An individual person who can authenticate and act as a principal.did associated with the account by ODF or an external system, and a password for local authentication, which is stored as a hash upon apply and is absent for SSO or DID-based accounts. A user can be suspended by setting disabled: true - the effects of suspension are implementation-specific.
Organization
An account that owns resources on behalf of a group of users, but cannot authenticate or act itself, so its resources are always accessed through its members.Group:acme/admins- organization administrators, initially containing the principal that created the organization. Members of this group have the same rights over resources owned by the organization as an owner would.Group:acme/members- organization members
Service Account
A non-human identity used by automation (scheduled flows, CI, installed applications) that can act as a principal but doesn’t own resources. Service accounts are always scoped under the owning account.Account Names
To avoid ambiguity and impersonation, nodes must ensure that names of nodes, users, and organizations are unique regardless of their resource type, making it possible to refer to any of these accounts by name alone. Service account names are exempt from this rule, as they are always scoped under the owning account. Some names cannot be used by accounts - see Reserved Names.Ownership
Every resource is owned by the account specified in itsheaders.account (see Resource Framework: Ownership). Only User, Organization, and Node accounts can own resources, and are referenced using ResourceOwnerRef, whose short form is the account name.
Owners hold all actions on the resources they own and on the entities materialized from them. For resources owned by an organization, the same rights are held by members of its {org}/admins group.
Principals
A principal is the identity performing an action in an authorization request. It is established through authentication and is always a single concrete identity.Organizationcannot authenticate - its resources are always accessed through its members.Anonymousrepresents unauthenticated requests. It is not a resource and carries no identity.- When a node executes work that belongs to a user or service account (e.g. a scheduled flow run) it should do so as that principal rather than as itself.
PrincipalRef, e.g. to specify the service account a flow runs as, or to record the initiator of an operation. Its short form requires a type prefix:
Subjects
A subject is the party a grant is given to in aPolicyBinding. Unlike a principal, a subject may stand for many principals at once.
Subjects are referenced using SubjectRef, which is a union of:
Short forms expand as follows:
Resource subject can alternatively be identified by id or did.
Authenticated, Anonymous, and Everyone can be used in policy bindings, but not as group members - otherwise nesting such a subject into a group would extend the group’s permissions to all principals.
Groups
AGroup resource represents a named set of subjects. Membership is declared inline in the spec. Groups support nesting - a group may include other groups as members. Only the Resource subject kind is allowed as a member.
Node account, like Group:node/admins, can be used to represent node-wide predefined roles.
Auth Attributes
Properties of a resource that directly affect access control (e.g. whether a dataset allows public reads) are expressed using resource labels (see Resource Framework: Labels and Annotations). A label schema that declareslabelProperties.isAuthAttribute: true signals that any resource carrying that label should have its value materialized into an auth attribute:
- Auth attributes must be labels, not annotations - validators must reject a resource that places an
isAuthAttributelabel underannotations - The value is validated against the label schema’s
typeat apply time - Implementations discover the set of auth attributes by enumerating label schemas with
isAuthAttribute: true, rather than hardcoding a list - Changing an auth attribute may require elevated permissions beyond those needed to update the rest of the resource (see
AddLabel) - Auth attributes are propagated from resources to the entities they define, e.g.
AllowPublicReadon a dataset resource (control plane) also appears as an attribute of the dataset entity (data plane)
Standard Auth Attributes
The effects of these attributes can also be achieved by binding policies to
Authenticated or Anonymous subjects. Attributes, however, are the primary way to make datasets public, as they are atomic with the resource manifest and can be efficiently filtered on when listing resources. Bindings to these subjects are better suited for granting other actions publicly, e.g. making a resource manifest viewable by everyone.
Actions
Authorization decisions are made against a set of well-defined actions. Each action is defined by a JSON schema using theAction metaschema:
- The schema URI is the canonical action identifier used in authorization requests and policies, e.g.
https://opendatafabric.org/schemas/resources/v1alpha1/actions/View - The schema describes the context values needed to authorize the action (e.g. the label being added for
AddLabel) actionProperties.objectTypeslists the types of objects the action applies to. Since resource types are an open set, every action must list its object types explicitly. Generic resource actions use theResourcetype to apply to resources of any type.
Resource Actions
Operate on resource instances. Exceptions areCreate and List, which operate on a resource type and receive the account under which resources are created or listed in the targetOwner context value.
AddLabel and RemoveLabel operate at the sub-resource level and are distinct from Edit to allow fine-grained control - a principal may be allowed to edit a resource, but be restricted from changing auth-sensitive labels like AllowPublicRead. Their context carries the type and the new (when adding) or existing (when removing) value of the label.
BindPolicy receives the subject of the binding being created in its context, so policies can restrict who is allowed to grant access to e.g. Everyone.
Dataset Actions
Operate on dataset entities in the data plane, separately from dataset resources.Config Actions
Operate on configuration entities.Policies and Policy Bindings
Beyond ownership,Policy and PolicyBinding resources are the primary mechanism for granting permissions:
- A
Policyis a reusable, potentially parameterized grant template. It declares what actions are permitted, but may leave the subject and object as slots to be filled in later. - A
PolicyBindinginstantiates aPolicyby supplying the concretesubject(SubjectRef) andobject(ResourceRef). Theobjectrefers to both the resource and the entity materialized from it.
PolicyBinding is itself an authorized operation - the principal creating it must hold the BindPolicy action on the referenced object. Resource owners implicitly hold BindPolicy on their own resources and can grant it to others, enabling delegated access management without transferring ownership.
A Policy resource’s kind field selects the policy language. The Generic kind must be supported by all nodes at maturity level 2 and above. Other kinds are engine-specific.
Higher-level features like dataset roles (Reader, Editor, Maintainer) are not part of this spec - implementations can build them using groups, Generic policy templates, and PolicyBinding resources.
Generic Policies
AGeneric policy grants a set of ODF actions. It is the portable building block - any node at maturity level 2 and above can evaluate it without a specialized policy engine. Its subject and object are always supplied by a PolicyBinding.
View on the dataset resource and Read on the dataset entity.
Engine-specific Policies
Nodes with a full policy engine may support richerPolicy kinds that can express attribute-based conditions, organization-scoped grants, and custom logic that Generic cannot. Engine-specific policies are not portable between implementations.
Engine-specific policies may declare slots for the subject and object, in which case they are templates instantiated via PolicyBinding. Policies that don’t declare slots take effect on their own without a binding (e.g. a node-wide policy granting all actions to members of Group:node/admins).
The Cedar kind carries a policy in the Cedar language, where ?principal and ?resource slots are filled in by the subject and object of a binding:
Policy kind must reject the resource with a clear error rather than silently ignoring it.
Access Token Scopes
Access tokens may be restricted to a set of scopes (e.g. read-only access to specific datasets). Scopes are not part of the authorization model: they can only narrow what the principal is allowed to do, so implementations check whether an action on an object falls within the token’s scopes before policy evaluation. Policies then decide based on the principal’s own permissions, so a token can never grant more than its owner has.Reserved Names
Names that implementations must reserve and treat consistently. Accounts - the following names cannot be used byUser or Organization accounts, to prevent impersonation of the node or its administrators:
Matching is case-insensitive. Implementations may reserve additional names (e.g. their own product name).
Groups - reserved groups are created together with the account that owns them and cannot be created or deleted independently:
Subject keywords - cannot collide with resource names, as resource references in short form always include a type prefix, a DID, or an ID:
Schemas
Appendix A: Cedar Example
Non-normative: This appendix illustrates how the authorization model maps onto the Cedar policy engine.Full prototype is available here. A schema can be code-generated based on types registered in the system allowing policies to be validated against known resource types and attributes:
Note: For brevity, actions here use short names (e.g."read"). A generated schema would use full action schema URIs (e.g."https://opendatafabric.org/schemas/datasets/v1alpha1/actions/Read") as in the examples above.
PolicyBinding resources become template-linked policies, with the ?principal slot filled based on the SubjectRef variant:
Appendix B: OpenFGA Example
Non-normative: This appendix illustrates how the authorization model maps onto the OpenFGA ReBAC engine.Full prototype is available here.
Note: This model predates theExample schema:ServiceAccountandNodeprincipals and is kept as an illustration of how the model maps onto a ReBAC engine.