Permissions Glossary¶
This glossary defines the canonical vocabulary for the b'nerd permissions model. The same terms are used in the API, the dashboard, and all documentation — one word per concept, everywhere.
Two independent axes govern every platform action:
- Axis A — Access (RBAC): "who can do what." Roles and permissions at the organization and project membership level. See Roles & RBAC.
- Axis B — Capabilities: "what a project may deploy." The chain: Limit → Grant → Available → Request.
Both axes must pass for an action to succeed. For example, creating a managed GitLab app requires apps:create permission on the project (Axis A) and GitLab in the project's Available kinds (Axis B).
Canonical terms¶
Limit¶
The maximum set of feature kinds the platform allows an organization to use. Set by b'nerd (platform admin) per organization, per feature. Org admins can read the Limit but cannot modify it.
When no Limit has been set for a feature, the organization is unbounded — any grantable kind may be enabled without restriction.
Backing API field: ceiling_configuration — present in GET /organizations/{id}/features/{feature_key} and GET /organizations/{organization_id}/projects/{project_id}/feature-grants. null means unbounded.
DB column: organization_features.ceiling_configuration
Grant¶
The set of feature kinds an org admin has authorized for a specific project, within the Limit. An org admin sets the Grant per project by calling the feature-grants endpoint. The Grant is always a subset of the Limit — attempting to grant kinds outside the Limit returns 422 exceeds_ceiling.
Backing API field: approved_configuration — in the feature-grants request body and in the grant response object. The raw allowed_kinds field inside approved_configuration reflects the stored Grant before ceiling intersection.
DB column: project_feature_requests.approved_configuration
See Feature Access & Grants for the full API reference.
Available¶
What actually works for a project — the server-computed intersection of the Grant and the current Limit: Available = Grant ∩ Limit.
Available is re-computed at runtime on every app-create attempt, so narrowing a Limit takes effect immediately for all projects in the org without revoking existing grants or stopping running applications.
Backing API fields (both expose Available; neither is renamed):
| Field | Endpoint | Notes |
|---|---|---|
effective_allowed_kinds | GET /organizations/{organization_id}/projects/{project_id}/feature-grants | Per-feature array in each grant entry. null when unbounded. |
effective_app_kinds | Project detail endpoint (GET /projects/{project_id}) | The apps capability's Available list from the project's perspective. |
Always prefer these server-computed fields over the raw allowed_kinds in approved_configuration when deciding which kinds a project may currently use.
DB column: not stored — computed on read from ceiling_configuration ∩ approved_configuration.
Request¶
An ask by a project member for feature access that is not currently Available. Any member may submit a Request for any feature, including provisioned-tier features (kubernetes, openstack) on projects that have not yet been provisioned. Submitting a Request is always permitted; how it is fulfilled depends on the provisioning tier (see Provisioning tiers below).
Backing API field: POST /projects/{project_id}/feature_requests
DB table: project_feature_requests (rows with status: "pending")
Request routing (§4a of the design):
| Condition | Fulfilled by |
|---|---|
Within Limit + self-service feature (apps, dns, object_storage) | Org admin approves in the dashboard |
Beyond Limit OR provisioned-tier feature (kubernetes, openstack) | b'nerd (superadmin) — requires manual provisioning first |
Members & Roles¶
The people in an organization or project and the roles that determine what they can do (Axis A — RBAC). At the organization level, a membership carries a role (admin, developer, operator, viewer, billing_manager) and optional per-category permission overrides. At the project level, memberships control access to project resources.
See Roles & RBAC for the full role and permission reference, and Glossary for the Membership and Preset definitions.
DB column → canonical term map¶
| DB column | Table | Canonical term |
|---|---|---|
ceiling_configuration | organization_features | Limit |
approved_configuration | project_feature_requests | Grant |
ceiling_configuration ∩ approved_configuration (runtime) | — | Available |
project_feature_requests rows with status: "pending" | project_feature_requests | Request |
Column names in the database are not renamed in the current release — the canonical terms are adopted in the API responses, UI labels, and documentation. A future release may align the column names.
Provisioning tiers¶
Features differ in how access becomes real once a Grant is in place.
| Tier | Features | What happens on approval |
|---|---|---|
| Self-service | apps (all kinds), dns, object_storage | Automated via platform operators (DPF, RGW). Approval alone is sufficient — no b'nerd wiring needed. Available immediately after org-admin approval. |
| Provisioned | kubernetes, openstack | Requires a manual b'nerd setup step per project (OpenStack credentials, Gardener project wiring) before the feature works. Request → b'nerd provisioning queue → b'nerd wires per-project backing → b'nerd approves → Available. |
Provisioning tier is not the same as billing
object_storage is a billed feature (requires_payment) but is self-service — no b'nerd wiring is needed. Do not infer provisioning tier from whether a feature is billed. kubernetes and openstack are the only provisioned-tier features.
The provisioned tier is tracked per project. The org-level Limit governs whether a feature is offered to the org at all; per-project provisioning governs whether it actually works for a given project. A Request on a not-yet-provisioned project is how b'nerd learns it must set up the per-project backing — submitting such a Request is always allowed.
The provisioning_tier field is exposed per feature in the GET /organizations/{id}/features/{feature_key} endpoint payload: "provisioning_tier": "self_service" or "provisioning_tier": "provisioned".