Skip to content

Introduce Policy Governance APIs in ate api. - #1625

Open
Shruti Nair (SHRUTI6991) wants to merge 1 commit into
agent-substrate:mainfrom
SHRUTI6991:authz-pg-tuple-store
Open

Introduce Policy Governance APIs in ate api. #1625
Shruti Nair (SHRUTI6991) wants to merge 1 commit into
agent-substrate:mainfrom
SHRUTI6991:authz-pg-tuple-store

Conversation

@SHRUTI6991

Copy link
Copy Markdown
Collaborator

Working on #1563

Summary

Introduces protobuf API definitions for resource-level authorization governance (GetPolicy and SetPolicy RPCs on service Control).

The API adopts a uniform, forward-compatible model that maps directly to OpenFGA's relationship-based authorization while remaining extensible for other authorization model like RBAC.

Design Highlights

  • Generic Resource Scoping (string resource): Uses canonical resource paths (e.g. "atespaces/team-a", "clusters/root") rather than resource-specific RPCs, allowing policies to apply uniformly across any Substrate resource.
  • AIP-132 Policy Model: Defines standard Policy, Binding (role + members), and optional Condition (CEL expressions for ABAC / time-bound access).
  • Optimistic Concurrency: Includes etag on Policy to support safe read-modify-write updates.
  • Isolated Scope: Covers API definitions, generated code, and declarative validation only. Storage persistence and evaluation will follow in subsequent PRs.

Changes

  • pkg/proto/ateapipb/ateapi.proto: Added GetPolicy / SetPolicy RPCs and Policy, Binding, Condition messages with +k8s: validation markers.
  • pkg/proto/ateapipb/: Regenerated protobuf stubs (ateapi.pb.go, ateapi_grpc.pb.go).
  • cmd/ateapi/internal/controlapi/zz_generated.validation.go: Regenerated declarative request validators.

Verification

  • ./hack/update/codegen.sh generated code cleanly.
  • go test -race ./... passed across all packages.
  • make verify passed.

@SHRUTI6991

Copy link
Copy Markdown
Collaborator Author

/assign Taahir Ahmed (@ahmedtd)

@SHRUTI6991
Shruti Nair (SHRUTI6991) marked this pull request as ready for review September 11, 2026 23:15
}

// Policy represents the access control policy for a resource.
message Policy {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think Policy is a very generic name. We already have EgressPolicy, and we will for sure have other policies. Can we think a more concrete name? AuthPolicy?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be AccessPolicy is a better name.

// The resource for which the policy is being requested (e.g. "atespaces/team-a", "clusters/root").
//
// +k8s:required
string resource = 1;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's discuss the resource model for auth policies. Do we want it to fit into the existing substrate resource model? Are they going to be resources (or sub-resources) themselves? Will each resource have a single policy attached to it? What represents the primary key of the policy. (see docs/api-style-guide.md).

@SHRUTI6991 Shruti Nair (SHRUTI6991) Sep 12, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want it to fit into the existing substrate resource model?

I actually tried this before. My primary concern is around retrofitting ObjectRef for cluster permissions which is built around atespace being the root:(atespace, name).

For auth, it starts from cluster: https://github.com/agent-substrate/substrate/blob/main/internal/authz/model.fga. Each resource has owner, editor, viewer permission. A cluster admin has the permission to create atespace. It can also give permissions to view atespaces to cluster viewer.

I actually prefer keeping the resource as string. Canonical strings like atespaces/team-a map directly 1:1 to OpenFGA too.

We can introduce GetClusterPolicy, GetAtespacePolicy but this kind of RPCs leads to resource explosion and isn't very scalable (imo).

Are they going to be resources (or sub-resources) themselves?

It should be a sub resource. The existence of an AccessPolicy is tied to the presence of parent resource like Atespace or Actor. Independent resource has their own lifecycles (similar to K8 roles) and I don't think this is necessary for substrate since our backing store is OpenFGA.

If the resource is deleted, the policies (openfga tuples) should be cascade deleted. cc: Taahir Ahmed (@ahmedtd) wdyt?

Will each resource have a single policy attached to it?

Yes this is strictly 1:1. Each resource has at most one policy attached to it which is why I used etag for guarding the policy state.

What represents the primary key of the policy?

We are going to store these as OpenFGA tuples which is defined as (user, relation, object. Relationship tuples are stored under OpenFGA's composite primary key.

PRIMARY KEY (store, object_type, object_id, relation, user_type, user_id, user_relation)

where object_type: cluster, atespace and object_id: root, team-a.

Design for full context: go/authorization-for-substrate

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Started a one pager to discuss: go/substrate-policy-governance-api. Let's take it there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants