Governance and Guardrails
Self-service only works if it's safe. The art of running DevsPortal for many teams is giving developers freedom within boundaries the platform team trusts — so a team can ship anytime without a ticket, but can't accidentally bypass standards, over-expose a service, or push straight to production. Those boundaries are guardrails, and on DevsPortal they are configuration and policy, not gatekeepers.
This page is the team-facing tour of the guardrails: what they are, how they keep you on the golden path, and where each is configured. The deep operator detail lives under operators/configuration.
DevsPortal is built on the Control Plane Operator engine. ComponentTypes,
Traits, Workflows, and the authorization resources named below are unchanged
openchoreo.dev/v1alpha1 engine concepts.
The guardrail toolkit
| Guardrail | Keeps teams on the golden path by… | Configured in |
|---|---|---|
| Approved ComponentTypes | Letting teams deploy only the workload patterns the platform blesses | Platform engineering (ComponentTypes / ClusterComponentTypes) |
| Approved Traits | Offering only vetted cross-cutting capabilities | Platform engineering (Traits / ClusterTraits) |
| Allowed Workflows | Restricting which builders a ComponentType permits | ComponentType allowedWorkflows |
| RBAC scopes | Confining a team's reach to its own projects | Roles and access |
| CEL conditions | Gating sensitive actions (e.g. prod) on request attributes | Conditions |
| Promotion gates | Controlling how releases advance through environments | DeploymentPipeline |
| Quotas | Capping a team cell's resource consumption | Operator config on the namespace/cell |
| Ownership | Attributing every resource to a responsible team | Ownership model |
Golden paths: ComponentTypes, Traits, Workflows
The strongest guardrail is the menu itself. Developers create components by picking a ComponentType — a template that encodes the approved workload shape, parameter schema, and resource templates. They can't deploy something off-menu; they pick from what the platform team published. The same goes for Traits (vetted capabilities) and the build Workflows a ComponentType allows.
On Fedshi this means a developer who runs occ clustercomponenttype list sees
exactly the patterns the platform team supports — for example a hardened deployment/service
with sane defaults baked in. They get freedom inside that template (replicas, ports,
endpoints, dependencies) without the platform team reviewing every component. Because these
are schema- and template-driven (parameters validated against JSON Schema, resources
rendered with CEL), a developer never sees raw Kubernetes, and the platform never sees a
non-conforming deployment.
If a team tries to use a workflow its ComponentType doesn't allow, the component enters a
WorkflowNotAllowed state — a guardrail surfacing as a clear, fixable error rather than a
silent escape hatch. See Builds and CI → troubleshooting.
Access and isolation guardrails
Two mechanisms keep teams in their lane:
- Scope. A team's role bindings are scoped to its project(s), so its members simply
can't see or touch other teams' resources. The cell model backs this at runtime: each
project is an isolated namespace with network policies, so cross-project traffic only
flows where an endpoint is deliberately exposed at
namespace(or broader) visibility. - Conditions. CEL conditions narrow when an action is allowed. The canonical example
is production: grant the team
developeraccess acrossdevelopmentandstaging, but gatereleasebindingmutations on production behind a condition, so only operators can ship the final hop.
# Most of the team can deploy and promote up to staging, but not mutate prod
conditions:
- actions: [releasebinding:create, releasebinding:update, releasebinding:delete]
expression: 'resource.environment != "fedshi/production"'
Both are detailed in Roles and access; the operator-side model is in Authorization and RBAC.
Promotion gates
The DeploymentPipeline a project binds to defines the promotion order and any gates
between stages. A team promotes the same release up the chain
(development → staging → production), and the pipeline — combined with the production
condition above — controls who advances it and when. This gives you a release process that's
auditable (every promotion is a binding to a named release) and reversible (rollback is just
deploying an earlier release) without a change-advisory board.
Quotas and cell limits
Each project is a runtime cell, and operators can cap what a cell consumes — CPU, memory, replica counts — so one team's runaway workload can't starve another's. Developers see this as ordinary Kubernetes scheduling limits; the caps are set on the cell by platform engineers during or after team onboarding.
Ownership as accountability
Guardrails are about prevention; ownership is about accountability when something does go
wrong. The backstage.io/owner annotation makes every resource traceable to a team, so the
right people are paged, the catalog stays navigable, and ownership-based policies can key off
it. See Ownership model.
The philosophy: paved roads, not gates
Done well, guardrails are invisible to a productive team. They feel like a paved road — the easy path is the compliant path — rather than a checkpoint. A team that picks an approved ComponentType, exposes endpoints at the right visibility, and promotes through the pipeline is compliant by construction, with no review queue. The platform team sets the boundaries once and lets every team move fast inside them. That's the contract that makes a multi-team internal developer platform work.
What's next
- Roles and access — the RBAC and conditions behind these guardrails.
- Onboard a team — where guardrails get applied to a new team.
- Authorization and RBAC (operators) — the platform-engineering side of the policy.