From 88ca983f43fbd94b6c8848d1661b2c61bdb7528c Mon Sep 17 00:00:00 2001 From: Rongsong Shen Date: Tue, 13 Oct 2026 04:13:35 +0000 Subject: [PATCH] docs(spec): project-config: project:submit RBAC implied by membership; project admins Submitting under a project becomes the RBAC permission project:submit, implied by membership (that project only) and grantable by roles (scope covers the subtree). A project's admins get every job permission and project:view over its subtree; they cannot edit the project, which only the cluster admin changes through config in this stage. Co-Authored-By: Claude Opus 5.5 (1M context) --- .kiro/specs/project-config/brief.md | 22 ++++++-- .kiro/specs/project-config/requirements.md | 64 +++++++++++++--------- 2 files changed, 57 insertions(+), 29 deletions(-) diff --git a/.kiro/specs/project-config/brief.md b/.kiro/specs/project-config/brief.md index b0d508e3..2aede70d 100644 --- a/.kiro/specs/project-config/brief.md +++ b/.kiro/specs/project-config/brief.md @@ -34,10 +34,13 @@ limits cannot be configured end to end, and nothing shows usage per project. - **Project selection** at submit: `-P` > the user's default project (if defined) > the cluster default > `"default"` (LSF p107 order, without environment variables). -- **Access check** at submit: the user must be a member of the project - (apiserver early check, controller authoritative), with a clear error; - `cluster_admin` keeps its existing bypass. Whether this is RBAC scope - (`project` scope type) or config membership is settled in requirements. +- **Access check** at submit (user decisions 2026-10-12): an RBAC + permission `project:submit`, implied by membership of the project and + grantable by roles (apiserver early check, controller authoritative), with + a clear error; `cluster_admin` keeps its existing bypass. +- **Project admins**: a project's `admins` get every job permission and + `project:view` over its subtree, implied by config like membership. Only + the cluster admin edits projects in this stage (config push). - **Quotas** (user decision 2026-10-12, replacing "`PROJECTS` / `PER_PROJECT` limits in `limits.yaml`"): written on the project itself, rolling up the tree, with pend reasons naming the project; see @@ -64,6 +67,7 @@ projects: members: [eng-ug] quota: { slots: 400, gpu: 16, mem: 2T } member_quota: { slots: 64 } # per user, over eng's whole subtree + admins: [eng-leads] # job control over eng's subtree - path: eng/hpc members: [alice, bob] quota: { slots: 200 } # must also fit eng @@ -111,6 +115,16 @@ projects: - **Adjacent**: `scheduler-sim-diagnostics` (`info limit`), `resource-distribution-mapping`, `rbac-persistence`. +## Design questions (RBAC, 2026-10-12) +- RBAC lives in the apiserver; the controller sees only config. Direct + client-library and harness submits bypass the apiserver, so there the + controller can honour membership and `cluster_admin` but not explicit role + grants. Options: the controller trusts an authorization basis passed by + the authenticated apiserver; or explicit `project:submit` grants apply on + the REST path only (documented). +- The job's authorization basis (Req 3.11) is a new job field: WAL fact and + scheduler snapshot must carry it (field completeness, `persistence.md`). + ## Constraints - Middleware chain unchanged; additive Cap'n Proto; old jobs keep their recorded project name even if the project is later removed from config diff --git a/.kiro/specs/project-config/requirements.md b/.kiro/specs/project-config/requirements.md index 27e34ee9..e2c326cc 100644 --- a/.kiro/specs/project-config/requirements.md +++ b/.kiro/specs/project-config/requirements.md @@ -12,10 +12,10 @@ Discovery brief: `.kiro/specs/project-config/brief.md`. Governing rules: `.kiro/ - `xcecli jobs list -P` is rejected by the apiserver ("unsupported filter"). - Nothing shows a project's usage. -**What should change (v1 = quota):** nested project definitions in cluster config, each with its own quotas; default-project resolution; a membership check at submit; project quotas enforced end to end and rolling up the tree; project visibility. Guarantees are `project-guarantee`. +**What should change (v1 = quota):** nested project definitions in cluster config, each with its own quotas; default-project resolution; a `project:submit` check at submit (implied by membership); project quotas enforced end to end and rolling up the tree; project visibility. Guarantees are `project-guarantee`. **Decisions (2026-10-10):** -- Access is by project membership. +- Access is by project membership (2026-10-12: membership implies the RBAC permission `project:submit`; roles may also grant it). - Open mode applies until any project is defined. - Default project: group default first, then the cluster default. - A pending job held by a project change pends with a reason. @@ -36,33 +36,38 @@ Discovery brief: `.kiro/specs/project-config/brief.md`. Governing rules: `.kiro/ - The full path is the project's identity and the only form a submit accepts; there is no last-segment shorthand. - Members are users and user groups (with `all` and excludes); a sub-project is never a member. +**Decisions (2026-10-12, project RBAC):** +- Submitting under a project is an RBAC permission, `project:submit` (scope type `project`), checked like `queue:submit`. +- Membership implies the grant: being a member of P gives an implicit `project:submit` on P only (membership is not inherited). Roles may also grant `project:submit` explicitly (e.g. to service accounts); a `project` scope covers the named projects and their subtrees, as for every `project` scope. +- Project admins: a project's `admins` (users and user groups) get an implicit grant of every job permission and `project:view` over the project's whole subtree. Being an admin does not imply `project:submit`. +- In this stage project definitions, members and admins change only through cluster config, so only the cluster administrator edits them; project admins manage jobs, not the project. + ## Introduction This feature makes projects first-class cluster configuration entities that control resource ownership. - **Definitions:** admins define a tree of projects named by path, each with its own members and quotas, and say which user groups default to which project. -- **Submit:** the system resolves each job's project, admits only members, and records the project on the job. +- **Submit:** the system resolves each job's project, admits only users holding `project:submit` on it (every member does), and records the project on the job. - **Quotas:** each project's quotas apply to its own and its descendants' jobs and roll up the tree, and a held job's reason names the project. - **Visibility:** users and admins can see projects and their usage against quotas. -- **RBAC:** roles can grant job permissions over a project subtree (project managers) and the right to view projects one does not belong to. +- **RBAC:** submitting under a project is the `project:submit` permission, implied by membership; a project's admins get job permissions over its subtree; roles can grant the same permissions explicitly. - **Compatibility:** a cluster that defines no projects keeps today's behaviour. ## Boundary Context - **In scope**: - - nested project definitions (path name, description, members, default-for groups, `quota`, `member_quota`) and a cluster default project; - - default-project resolution, membership check at submit, and an "open" mode when no projects are defined; + - nested project definitions (path name, description, members, admins, default-for groups, `quota`, `member_quota`) and a cluster default project; + - default-project resolution, the `project:submit` check at submit, and an "open" mode when no projects are defined; - pending-job behaviour when a project or membership changes; - project quotas compiled into the scheduler's limits, applying end to end and rolling up the tree, with project-naming pend reasons; - rejecting project-scoped entries in `limits.yaml`; - overlapping membership (a user in several projects); - project listing (as a tree) and detail with usage against quotas; - - RBAC: a `project` scope for job permissions (covering the project's subtree) and a `project:view` permission; + - RBAC: a `project:submit` permission implied by membership; project admins with implied job permissions over the subtree; a `project` scope for job permissions (covering the project's subtree) and a `project:view` permission; - job filtering by project. - **Out of scope**: - guaranteed shares, owned pools, borrowing, reclaim (`project-guarantee`); - fairshare; - any project influence on job ordering or priority (queues own ordering); - accounting history and billing of finished jobs; - - RBAC gating of which project a job is submitted under (membership decides; the existing queue permission still applies); - - runtime (delegated) membership edits by project managers (future; membership changes only through cluster config); + - runtime edits of a project's members, admins or quotas by project admins (`project-delegated-membership`; in this stage only the cluster administrator changes them, through cluster config); - per-user default projects in `users.yaml`; - membership inherited between parent and child projects; - moving or renaming a project while keeping its jobs' recorded name; @@ -84,10 +89,10 @@ This feature makes projects first-class cluster configuration entities that cont **Objective:** As a cluster admin, I want to define projects and their members in the cluster configuration, so that project ownership is explicit and versioned with the rest of the cluster config. #### Acceptance Criteria -1. The configuration tool shall accept project definitions consisting of a path name, an optional description, members (user names, user-group names, or `all`), optional excluded members, an optional list of user groups for which the project is the default, an optional `quota` and an optional `member_quota`, each a map from resource name to an absolute amount. +1. The configuration tool shall accept project definitions consisting of a path name, an optional description, members (user names, user-group names, or `all`), optional excluded members, optional admins (user names or user-group names), an optional list of user groups for which the project is the default, an optional `quota` and an optional `member_quota`, each a map from resource name to an absolute amount. 2. The configuration tool shall treat a path name of one segment (e.g. `eng`) as a top-level project and a path of several `/`-separated segments (e.g. `eng/hpc/cfd`) as a child of the project named by the path without its last segment. 3. The configuration tool shall accept an optional cluster default project naming one defined project. -4. If a project definition repeats a path name, uses a reserved name, has an empty or malformed path segment, names a parent project that is not defined, names an undefined user group, lists a default-for user group that is not covered by the project's members, or has a `quota` or `member_quota` entry naming an undeclared resource or giving a negative, non-numeric or percentage amount, then the configuration tool shall reject the configuration with an error identifying the project and the offending field. +4. If a project definition repeats a path name, uses a reserved name, has an empty or malformed path segment, names a parent project that is not defined, names an undefined user group (in members, excluded members or admins), lists a default-for user group that is not covered by the project's members, or has a `quota` or `member_quota` entry naming an undeclared resource or giving a negative, non-numeric or percentage amount, then the configuration tool shall reject the configuration with an error identifying the project and the offending field. 5. If the cluster default project names an undefined project, or a project whose members do not include every user, then the configuration tool shall reject the configuration with an error naming the cluster default project. 6. When a configuration with changed project definitions is applied by live configuration upgrade, the Cluster shall apply the new definitions to all subsequent submissions and scheduling decisions without a restart. 7. The Cluster shall keep project definitions, including their quotas, across controller failover and restart identically to other cluster configuration. @@ -104,33 +109,37 @@ This feature makes projects first-class cluster configuration entities that cont 5. The Cluster shall apply the same project resolution to every submit path (REST API, `xcecli`, harness and client library) and to every element of a job array. 6. The Cluster shall identify a project at submit only by its full path name; a name that is only the last segment of a defined project's path (e.g. `cfd` for `eng/hpc/cfd`) is treated as the top-level project of that name. -### Requirement 3: Membership check at submit -**Objective:** As a cluster admin, I want only a project's members to submit work under it, so that projects control who may use their resources. +### Requirement 3: Submit authorization +**Objective:** As a cluster admin, I want only users allowed on a project to submit work under it, so that projects control who may use their resources. #### Acceptance Criteria -1. While at least one project is defined, when a job is submitted under a project whose members include the submitter, the Cluster shall accept the job's project. -2. If, while at least one project is defined, a job is submitted under a project whose members do not include the submitter, then the Cluster shall reject the submission with an error naming the project and stating that the user is not a member. +1. While at least one project is defined, when a job is submitted under a project, the Cluster shall accept the job's project if the submitter holds `project:submit` on it: implicitly as a member of that project, or through a role grant whose scope covers it. +2. If, while at least one project is defined, a job is submitted under a project on which the submitter does not hold `project:submit`, then the Cluster shall reject the submission with an error naming the project and stating that the user may not submit under it. 3. If, while at least one project is defined, a job is submitted under a project name that is not defined, then the Cluster shall reject the submission with an error naming the unknown project. -4. Where the submitter has the cluster administrator role, the Cluster shall accept any defined project without a membership check. +4. Where the submitter has the cluster administrator role, the Cluster shall accept any defined project without a further check. 5. The Cluster shall treat a user as a member of a project if the user is listed directly in that project's own members, belongs to a user group listed there, or those members include `all`, and the user is not excluded there. -6. The Cluster shall not infer membership of a project from membership of its parent, its children or any other project. -7. Where a user is a member of several projects, the Cluster shall accept the user's jobs under any of those projects. -8. The Cluster shall reject a non-member or unknown-project submission before the job is assigned a job ID or recorded, on every submit path. +6. The Cluster shall not infer membership of a project from membership of its parent, its children or any other project; the implicit `project:submit` of a member covers that project only. +7. The Cluster shall treat a role grant of `project:submit` with scope type `all` as covering every project, and with scope type `project` as covering the named projects and their descendants. +8. Where a user may submit under several projects, the Cluster shall accept the user's jobs under any of those projects. +9. The Cluster shall reject an unauthorized or unknown-project submission before the job is assigned a job ID or recorded, on every submit path. +10. The Cluster shall check `project:submit` in addition to, not instead of, the existing queue permission. +11. The Cluster shall record on the job whether its project was authorized by membership, by a role grant or by the cluster administrator role. ### Requirement 4: Open mode when no projects are defined **Objective:** As an operator of an existing cluster, I want clusters without project definitions to keep working as today, so that upgrading does not break existing submissions. #### Acceptance Criteria -1. While no project is defined in the cluster configuration, the Cluster shall accept any project name at submit without a membership check. +1. While no project is defined in the cluster configuration, the Cluster shall accept any project name at submit without a `project:submit` check. 2. While no project is defined in the cluster configuration, when a job is submitted without a project name, the Cluster shall record the project `default`. 3. When the first project definitions are applied to a cluster that had none, the Cluster shall apply Requirement 5 to pending jobs whose recorded project is undefined or does not include their owner. +4. While no project is defined, the Cluster shall not check `project:submit`. ### Requirement 5: Pending jobs after project changes **Objective:** As a cluster admin, I want project changes to take effect on work that has not started, without disturbing running work, so that removing a project or a member is effective and reversible. #### Acceptance Criteria 1. If, while projects are defined, a pending job's recorded project is no longer defined, then the Scheduler shall keep the job pending with a reason naming the project and stating that it is not defined. -2. If a pending job's owner is no longer a member of the job's recorded project, then the Scheduler shall keep the job pending with a reason naming the project and stating that the owner is not a member. +2. If a pending job's project was authorized by membership and its owner is no longer a member of the job's recorded project, then the Scheduler shall keep the job pending with a reason naming the project and stating that the owner is not a member. A job authorized by a role grant or the cluster administrator role is not held when roles change. 3. When a later configuration change makes a held job's project defined again, or restores its owner's membership, the Scheduler shall consider the job for scheduling again without user action. 4. While a job is running, the Cluster shall not stop, requeue or alter the job because of a change to its project's definition or membership. 5. The Cluster shall allow an admin to kill or modify a job held by Requirement 5 using the existing job controls. @@ -154,16 +163,16 @@ This feature makes projects first-class cluster configuration entities that cont **Objective:** As a user or admin, I want to see projects, their members and their usage against quotas, so that I know which projects I can use and why a job is held. #### Acceptance Criteria -1. When a user lists projects through the REST API or `xcecli`, the Cluster shall return every project the user is a member of, with its full path name and description, shown in tree order, and mark the project that would be the user's default, so that a submit client can offer them for choosing the project to charge. +1. When a user lists projects through the REST API or `xcecli`, the Cluster shall return every project the user may submit under (as a member or through a role grant) or administers, with its full path name and description, shown in tree order, and mark the project that would be the user's default, so that a submit client can offer them for choosing the project to charge. 2. Where the requester has the cluster administrator role, or a `project:view` permission covering a project, the Cluster shall include that project in the list with its members, excluded members and default-for user groups. 3. When a user requests a project's details, the Cluster shall show, for the project and for each of its ancestors, every `quota` and `member_quota` entry with the project it is set on, the resource, the amount and the current usage counted against it (including descendants' jobs; for `member_quota`, the requesting user's own usage, and every user's usage to an admin or a holder of `project:view` covering the project). -4. If a user requests the details of a project they are not a member of, and they have neither the cluster administrator role nor a `project:view` permission covering the project, then the Cluster shall reject the request without revealing the project's members or usage. +4. If a user requests the details of a project they are neither a member nor an admin of, and they have neither the cluster administrator role nor a `project:view` permission covering the project, then the Cluster shall reject the request without revealing the project's members or usage. 5. When a user lists jobs filtered by project through the REST API or `xcecli`, the Cluster shall return only jobs with that recorded project, or, when the user asks to include sub-projects, with that project or any descendant, subject to the user's existing job-visibility permissions. 6. While no project is defined, the Cluster shall report that projects are not configured when projects are listed. 7. The scheduler's diagnostic interface shall show, for a named project, the quotas that apply to it (its own and its ancestors') and their current usage. ### Requirement 8: Project-scoped access control -**Objective:** As a cluster admin, I want to grant a project manager rights over the jobs and details of a project and its sub-projects, so that project leads can manage their project's work without being cluster administrators. +**Objective:** As a cluster admin, I want project admins and roles to hold rights over the jobs and details of a project and its sub-projects, so that project leads can manage their project's work without being cluster administrators. #### Acceptance Criteria 1. The Cluster shall accept roles that grant a job permission (view, kill, modify or any other existing job permission) with the scope type `project` and a list of project path names as scope values. @@ -173,7 +182,12 @@ This feature makes projects first-class cluster configuration entities that cont 5. The Cluster shall accept roles that grant `project:view` with the scope type `all` or `project`; a `project` scope covers the named projects and their descendants. 6. If, while projects are defined, a role is created or updated with a `project` scope value that names an undefined project, then the Cluster shall reject the change with an error naming the unknown project. 7. While a `project` scope value names a project that is no longer defined, the Cluster shall treat that value as covering no project. -8. The Cluster shall leave the behaviour of existing roles and grants unchanged; the default RBAC configuration shall grant no `project`-scoped permission to any role other than the cluster administrator. +8. The Cluster shall leave the behaviour of existing roles and grants unchanged; the default RBAC configuration shall grant no `project`-scoped permission and no explicit `project:submit` to any role other than the cluster administrator. +9. The Cluster shall accept roles that grant `project:submit` with the scope type `all` or `project`. +10. The Cluster shall treat each admin of a project (a listed user, or a member of a listed user group) as holding every job permission and `project:view` with scope `project` on that project, which covers its subtree, without any role assignment. +11. The Cluster shall not give a project admin `project:submit` on the project, nor any right to change a project's definition, members, admins or quotas, by being its admin. +12. When a configuration change adds or removes a project admin, the Cluster shall apply the change to all subsequent requests without a restart. +13. When a user lists their projects, the Cluster shall mark the projects the user administers. ### Requirement 9: Compatibility and durability **Objective:** As an operator, I want projects added without data migration or downtime, so that existing jobs and records keep working.