Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 136 additions & 0 deletions docs/developers/serviceprovider/07-quality-standards.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
---
sidebar_position: 7
id: quality-standards
---

# Quality Standards

This page defines the quality standards a `ServiceProvider` should meet to be considered ready for use in different kinds of OpenControlPlane landscapes, from early-stage experiments to production environments with corporate compliance requirements.

The standard exists for two audiences:

1. **Service provider developers** read it as a checklist. It tells you what you need to implement.
2. **Platform owners** read it to evaluate whether a service provider is mature enough to install in their landscape.
Comment on lines +10 to +13
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I do believe the Service Provider developer is the main driver behind these quality standards. The platform owner is more or less the stakeholder for these requirements. Both have are interested in this. I am not sure if developers/serviceproviders/ is the right path to put this in. What do you think @christophrj?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Imo it is fine to put this in developers/... and then reference it somewhere in operators/...


The standard is **tooling-agnostic**. It describes what a service provider must *produce* (its artifacts) and how it must *behave* (at runtime), not how it is built. Service providers in any GitHub organisation can adhere to it, regardless of the build system or CI they use.

## Tiers at a glance
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Community (governance/ownership) feels like a different dimension vs Stable and Experimental (technical maturity).

ownership dimension could be Official (provided by the core team) and Community and maybe something in between like Verified which aligns with your suggestion of core maintainers reviewing external community repos.

When I look at the overview table that is provided at the end of this document, maybe rename the tiers to Experimental, Stabilizing and Stable/Production-ready?


| Tier | Suitable for | Not suitable for |
| ------------------ | ------------------------------------------------------------------------------------- | -------------------------------------------------------------- |
| <img src="https://img.shields.io/badge/Quality-Experimental-e69138?style=flat-square&labelColor=555" alt="Quality: Experimental" /> | Proof-of-concept, evaluation, contributor hacking | Anything you don't want to clean up by hand if it breaks |
| <img src="https://img.shields.io/badge/Quality-Community-3d9970?style=flat-square&labelColor=555" alt="Quality: Community" /> | Dev/test landscapes, internal platforms, situations where rough edges are tolerable | Regulated or production environments without additional review |
| <img src="https://img.shields.io/badge/Quality-Stable-1e8f95?style=flat-square&labelColor=555" alt="Quality: Stable" /> | Production landscapes, customer-facing platforms, corporate / air-gapped environments | |

Each tier is a **floor**, not a ceiling. A Community-tier provider may satisfy Stable-only criteria — it just isn't required to.

## The quality criteria
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please add a section regarding required annotations where we point to our controller guidelines https://open-control-plane.io/developers/general#operation-annotations


The tier matrix later on this page shows which criteria are required at which tier.

### 1. Deletion behaviour

When a user triggers an uninstall of a domain service through the `ServiceProviderAPI`, the service provider must not blindly remove the domain service and its CRDs from the managed `ControlPlane`. Domain services like Crossplane, Flux, or ESO install CRDs into the `ControlPlane`, and users may have created instances of those CRDs. Deleting the CRDs while custom resources still exist would leave those resources orphaned in the cluster or cause managed resources in external systems to escape the platform's control.

Before uninstalling, the service provider checks whether any custom resources belonging to the domain service still exist on the managed `ControlPlane`. If they do, the provider blocks deletion and surfaces a clear message explaining what needs to be cleaned up first.

### 2. Status phases and conditions
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think it makes sense to add a link to the status reporting section of our controller guidelines here https://open-control-plane.io/developers/general#status-reporting


Every `ServiceProviderAPI` reconciled by the service provider carries a `Status.Phase` (`Ready` / `Progressing` / `Terminating`) and typed `Conditions` (at minimum `Ready`, plus type-specific ones). Conditions follow the `metav1.Condition` shape with `reason` and `message`.

### 3. Clear error messages
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I would merge this with section 2 to have one error/status reporting section


When reconciliation fails, the cause appears on a Condition's `message` and as a Kubernetes Event on the `ServiceProviderAPI`. Messages are actionable — they name the missing or invalid input, or the upstream system that failed.

### 4. API stability policy
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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


The provider declares its API maturity per CRD (`v1alpha1`, `v1beta1`, `v1`) and follows the matching change policy. Breaking changes at `v1beta1`+ require a deprecation cycle. Conversion webhooks exist when multiple versions are served.

### 5. Air-gapped / custom CA bundle support
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Imo these are features and not quality standards


The provider supports custom CA bundles so it can operate in air-gapped or corporate environments that use private certificate authorities. The CA bundle is propagated to all relevant components of the domain service, ensuring that outbound connections and external integrations trust the custom certificates.

### 6. Release artifacts

Each tagged release publishes a multi-architecture container image and an OCM component descriptor referencing that image. Both are pushed to a publicly resolvable registry. Without published artifacts, no landscape can install the provider through the OpenControlPlane onboarding system.

### 7. Security hardening

The controller's container runs with `runAsNonRoot: true`, `readOnlyRootFilesystem: true`, `allowPrivilegeEscalation: false`, and drops all Linux capabilities. RBAC is split between cluster-scope (only what is truly needed) and namespace-scope. No wildcards on critical verbs (`*` on `secrets`, etc.).
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Not sure if we want to add it to our quality standards right from the beginning. The topic is way more deep and I am a bit unsure wether this is just a scratch on the surface which is not really helping a service provider developer or platform owner.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We could reference the build repo here regarding a recommended base image https://github.com/openmcp-project/build/blob/main/Dockerfile in case a developer chooses to not use the sp-template setup.

Regarding the deployment settings, those are managed by the openmcp-operator so I assume there is no way to ignore those settings, right?


### 8. Testing
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Imo if we define a testing section then it is our responsibility to provide an integration test that a service provider has to pass, rather than dictate any unit testing goals that might not meet any quality standard that we aim for. For now openmcp-testing is a good starting point and we can think about extending this with an integration test suite to check that a service provider is "well-behaved" in the future.


**Community** requires unit tests covering the reconciler. **Stable** additionally requires end-to-end tests run on every release against a real cluster. Tests must cover the full lifecycle: install, reconcile, and delete. The [openmcp-testing](https://github.com/openmcp-project/openmcp-testing) framework provides tooling for this within the OpenControlPlane ecosystem; equivalent frameworks are acceptable.

### 9. Maintenance signals
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Imo signals is a little misleading in this context. Maybe Ownership and Maintenance Documentation?


A `MAINTAINERS.md` or `CODEOWNERS` file names responsible humans or teams. The repo declares its support level (best-effort, business-hours, etc.).


## Declaring a tier in your service-provider repository

Each service-provider repository carries a **Quality Standards block** in its README, placed directly below the title and badges and above the "About this project" section. It has three parts.

### 1. Tier badge

A badge showing the tier you claim. Copy the snippet for your tier from the [Badge snippets](#badge-snippets) section below and paste it into your README.

### 2. Compliance table

A table showing the status of every criterion. Three states:

- ✅ **Met** — the criterion is fully satisfied.
- ❌ **Not met** — the criterion is not satisfied.
- ⚠️ **Partial** — some aspects are met, with known gaps documented (link to a tracking issue if available).

The tier you claim is a **floor**: every cell that the tier requires must be ✅. You may also have ✅ entries for criteria the tier does not require — that is encouraged and visible to platform owners.

### 3. Link to the canonical standard

A link back to this page so anyone reading the table can find the definitions.

### Example

```markdown
## Quality Standards

![Quality: Community](https://img.shields.io/badge/Quality-Community-3d9970?style=flat-square&labelColor=555)

| Criterion | Status |
| ------------------------------- | :----: |
| Deletion behaviour | ✅ |
| Status phases & conditions | ✅ |
| Clear error messages | ✅ |
| API stability policy | ✅ |
| Air-gapped / custom CA | ❌ |
| Release artifacts (image + OCM) | ✅ |
| Security hardening | ⚠️ |
| Testing | ✅ |
| Maintenance signals | ✅ |

See the [OpenControlPlane Quality Standards](https://open-control-plane.io/developers/serviceprovider/quality-standards) for definitions.
```

### Badge snippets

Copy the badge for your tier and paste it into your README directly below the `## Quality Standards` heading:

**Experimental**

```markdown
[![Quality: Experimental](https://img.shields.io/badge/Quality-Experimental-e69138?style=flat-square&labelColor=555)](https://open-control-plane.io/developers/serviceprovider/quality-standards)
```

**Community**

```markdown
[![Quality: Community](https://img.shields.io/badge/Quality-Community-3d9970?style=flat-square&labelColor=555)](https://open-control-plane.io/developers/serviceprovider/quality-standards)
```

**Stable**

```markdown
[![Quality: Stable](https://img.shields.io/badge/Quality-Stable-1e8f95?style=flat-square&labelColor=555)](https://open-control-plane.io/developers/serviceprovider/quality-standards)
```

These render identically on GitHub, GitLab, and the OpenControlPlane docs site.