Governance and product modules¶
Platform policy lives in Composition input. Request authors select approved names and supply their own workload definitions; they cannot supply policy ceilings or credential values. Catalog examples are inert Kustomize bases. Only enabled/* is watched for live requests. Product credentials use identity-bound bootstrap exchanges; provider readiness is not live product proof.
Token lifetime and where tokens may be used¶
spec.maximumTokenLifetime in the platform Composition input is mandatory. Missing, malformed, zero, negative or sub-second values fail closed. The administrator, Fleet Management and telemetry rotating tokens use the lesser of the standard 30-day request and the platform ceiling. The seven-day early rotation window is shortened when needed to remain strictly inside that lifetime. Each provider-observed expiry appears in status.tokenExpiries.administrator, fleetManagement or telemetryPublisher; a timestamp is absent until the provider supplies it. These are observed expiries, not predicted rotation times.
spec.tokenUseNetworkProfiles selects allowedSubnets using the stack's immutable profile. It applies to the Fleet Management and telemetry Cloud access policies. If the profile has no subnet list, no conditions block is emitted. An explicitly empty subnet list is rejected so a mistaken restriction cannot silently become unrestricted token use. Request authors cannot pass CIDRs through the stack API. This restricts where those tokens may be used from. It does not filter inbound traffic to a Grafana stack and does not add a subnet condition to the Grafana administrator service-account token.
Golden SLO¶
A platform goldenSLOProfiles entry keyed by usage supplies a ratio objective, queries and destination datasource UID. The stack observes that datasource before rendering its SLO. The SLO is created in handoff mode, with initial parameters under initProvider, so service teams can own later changes. Grafana generates recording rules and fastburn, slowburn and budget-remaining alerts from the SLO. The function does not invent workload metrics or include the preview alert-enrichment assistant block.
The golden SLO catalog supplies inert ratio metric names. Adopters must replace the entire profile with reviewed workload queries and an existing datasource. A locally rendered resource does not prove those queries return useful traffic.
k6 projects¶
GrafanaK6Project vends a project, ProjectLimits and ProjectAllowedLoadZones. Platform k6LimitProfiles select monthly VUH, per-test VUs, browser VUs and maximum duration from the referenced stack's immutable usage. Requested load zones must be an explicit subset of the platform list. An empty array allows no private zones; omission is rejected. The module adds explicit load tests and schedules after the project caps are observed Ready; it never creates private load zones. Admission checks the declared test VUs, browser VUs, duration and zones against the Composition profile, and reconciliation rejects a usage declaration that differs from the observed stack. The function generates a structured HTTPS GET script from those admitted fields; arbitrary JavaScript is not accepted. k6 owns runtime enforcement of ProjectLimits. Schedules wait for observed LoadTest IDs and have Delete management enabled; the tests prove that declarative deletion path, not live remote deletion.
Installation exchanges the referenced stack's observed service-account token and a supplied Grafana user for a derived k6 credential. The function resolves the referenced stack and canonical local bootstrap Secret by identity, and passes references rather than token values. The derived credential is the downstream k6 provider credential and the only credential this module publishes to the secret store. The pinned provider's Installation fields and connection mapping are the compatibility contract; its upstream credential surface has changed rapidly.
Synthetic Monitoring¶
GrafanaSyntheticMonitoring uses the existing local telemetry access-policy token, whose scope includes stacks:read, metrics, logs and traces write. It publishes only the derived Synthetic Monitoring credential. Private probe tokens belong in secret-store outputs and never in composite status.
Installation Ready alone is insufficient: an upstream defect can report creation complete while Synthetic Monitoring is not configured. Children require a disabled verification Check created and read through the derived-token SM provider. It targets a reserved .invalid address and schedules no executions. Its Ready condition plus observed tenant identity verifies a tenant-scoped API operation; public probe inventory is only an input and is not installation proof. This API creates no private probes or probe tokens.
Consuming teams author explicit check definitions. The Composition validates the whole submitted set against platform limits for count, probe locations, frequency and weighted executions, with browser executions costed separately. It never invents targets. This caps the API's managed checks, not a service-side tenant quota. Adopters must deny request authors direct writes to provider Check resources and platform policy, or those paths bypass the budget.
Promotion ladders and tenancy¶
GrafanaStackLadder declares ordered rungs, branch-specific provisioning repositories, and an explicit forward or reverse content direction. Status records each rung's readiness, observed revision, source rung and drift. A missing revision means Unknown, not in sync. Promotion remains a reviewed Git operation; the renderer writes no Git content.
Organization, region and rung identities are immutable. Grafana's region slug forces replacement, so changing region requires a separately reviewed migration, never a ladder promotion. Cloud stacks are single-organization. Free plans allow one stack and self-service paid plans three; larger ladders require a negotiated cap, reflected in platform ladderPolicy.maxStacks. Multi-stack datasources require one region and were limited to ten stacks in preview.
Both shared-stack and stack-per-tenant topologies are supported deliberately. Grafana recommends one production stack with teams, folders, RBAC, datasource permissions and LBAC for isolation, and also supports multiple stacks for dev/staging ladders and complete departmental isolation. The stack API supports stack-per-tenant; the access APIs support slices of a shared stack. Shared stacks reduce stack count and centralize operations; separate stacks give stronger lifecycle isolation at the cost of duplicated configuration and contractual limits.
Retention is decided at creation¶
spec.retention.class is immutable and must be selected at creation. It selects platform-owned Fleet Management collector configuration for durable fan-out from the start of the stack's life. The request cannot supply contents, destination credentials, or a retention period. A configured Pipeline proves the control-plane resource; an adopter must separately verify collector selection, receipt at the durable sink and the sink's retention policy.
Cloud Logs export syncs Loki chunks to a customer-owned bucket over a rolling window of roughly seven to thirty days. It extends retention forward and does not dump history. No equivalent bulk export was found for metrics or traces. Logs retention has a self-serve API in thirty-day multiples up to one year; values below thirty days need a support request. The logs API is not reconciled by this Composition and remains a future integration option. Metrics and traces have no self-serve retention API.
Stack deletion is permanent. Review 1 of the decommission runbook must verify the creation-time retention decision and durable fan-out evidence. Adding fan-out during decommission cannot recover telemetry that was never forwarded.
SCIM remains outside the API¶
The supported identity model is Team Sync external-group mapping through GrafanaTeamAccess.spec.team.externalGroups and GrafanaCustomRoleBinding.spec.team.groups. Team Sync maps groups onto existing Teams; these APIs create and reconcile those Teams. SCIM group sync can create and delete Teams from identity-provider changes, so it is mutually exclusive with that ownership model.
The schema rejects non-null SCIM input. Real API-server readback proves that explicit spec.scim: null is admitted and persisted with its key present; CEL has() does not see the null-valued field. The function sees that persisted key and refuses reconciliation with zero children. The owner accepted this reconcile-time boundary on 2026-09-08, including attempts to mix SCIM with external-group mappings. No SCIM configuration is supported. SAML's external-UID assertion attribute alone is not treated as SCIM activation.
Enabling SCIM later is a breaking migration for every existing tenant using these mappings. A future contract must couple SCIM, SAML SSO and an external-UID assertion attribute matching the identity provider's SCIM identifier. The identity-provider half has no declarative coverage and would require manual per-tenant setup. Any migration must inventory and resolve existing Team ownership before activation; its reversal cost grows with tenant count.
The repository owner, acting as Grafana staff, answered both product questions on 2026-09-08: SCIM is available on all Grafana Cloud plans; disabling user sync leaves already-provisioned users unchanged and frozen. Their records remain active, authentication continues, and identity-provider updates stop. Disabling sync is therefore reversible and non-destructive. These are owner statements, not claims attributed to dated public documentation. The pinned provider includes enterprise/ScimConfig with enableUserSync, enableGroupSync and rejectNonProvisionedUsers; its schema does not establish disable semantics. Neither answer reopens the SCIM exclusion.
Sandbox expiry uses the reviewed deletion path¶
Only platform-approved usage classes may select expiry. The function compares the injected reconcile time with the original deadline plus recorded extensions. Extension records are append-only; requestedBy and recordedAt are declared provenance and must be correlated with Kubernetes audit logs for authenticated actor and server time.
Expiry controls when Review 1 can arm deletion. The request must already declare lifecycle.externalResources: Delete, and the platform must authorize its exact namespace, name, UID and immutable profile. Authorization is validated before the deadline as well. Before the effective deadline, deletion fields stay in Retain mode; at the deadline, the same existing armed-delete fields are rendered and observed deletion readiness is reported. A timestamp alone never authorizes destruction.
Review 2 still removes dependent access claims and waits for their finalizers. Review 3 still removes the stack request in a separate reviewed Git change. Expiry does not delete the request, remove access claims, or bypass either review. Warnings use the already-vended production incident contact point; an approved expiry policy must name its warning lead time and folder, and the stack must have that delivery path configured.
Temporary product bootstrap or verification interruptions abort reconciliation before withdrawing existing children. The composite remains unready until the missing prerequisite returns; explicitly removed team-authored checks can still be removed.
Synthetic Monitoring owns deletion of its checks and disabled verifier. Removing a check from the whole list removes its external Check; rotating the derived credential retires the old verifier. This explicit ownership prevents orphaned active checks from continuing to consume the budget. Stack deletion still follows the separate reviewed lifecycle.
The temporary expiry warning RuleGroup is deletion-managed so leaving the warning window removes the external alert instead of orphaning a firing rule. This policy applies only to that warning, not to Stack deletion.
Decommission runbook¶
The default spec.lifecycle.externalResources: Retain is safe for ordinary pruning: removing an unarmed request from Git or pruning it from Argo orphans external resources. Stack-local Grafana content is safe to orphan because deleting the Stack destroys it; credential-bearing state that can outlive the Stack is the state covered by the optional Delete path.
An actual deletion has three reviewed Git stages. It is not a one-command path. Approved sandbox expiry can delay Stage 1 arming until the effective deadline; it never executes Stages 2 or 3. See Governance.
Review 1: arm deletion¶
- Inventory and record the exact stack identity (
status.stack.id, slug, and URL), dependants, access claims, credential consumers, and data-retention requirements. Verify the creation-timespec.retention.classdecision and actual receipt at its durable fan-out sink; decommission cannot recover telemetry that was never forwarded. - Have the platform owner add this request's exact namespace, name, Kubernetes UID, and immutable profile to the platform-owned
deletionAuthorizationslist. If there is no exact match, stop; the request must remainRetain. - Change only the request lifecycle intent to
spec.lifecycle.externalResources: Deleteand submit that change for review. Arming is intent only; it does not delete anything. - After reconciliation, confirm
status.deletionArmed=true. Wait forstatus.deletionReady=true; this means observed provider state reports the Stack'sdeleteProtection=falseand ESO has installed its deletion finalizer and successfully synced each enabled external credential document at the current generation. Do not proceed on desired specs or a stale Ready condition alone. New access claims fail closed as soon as deletion is armed; already-observed access children remain managed until Stage 2 removes their claims.
Review 2: remove access claims¶
- In Stage 2, remove all dependent
GrafanaCustomRoleBinding,GrafanaTeamAccess, andGrafanaContentAccessPolicyobjects. Merge or sync this change and wait until each access-claim Kubernetes object and its finalizer are gone while the Stack and its request still exist. Do not remove the request until this check passes.
Review 3: remove the stack request¶
- In a third reviewed change, remove the
GrafanaCloudStackRequestfrom Git only after the dependent access claims and their finalizers have cleared. - Let Crossplane and ESO reconcile the armed deletion. The Delete mode covers only the Stack, its administrator service account and token, the telemetry access policy and token, and the administrator and telemetry
PushSecretdocuments. Stack-local Grafana content remains retain/orphan because Stack deletion destroys it. - Verify the external deletion result and the credential-document outcome. AWS Secrets Manager deletion defaults to a 30-day recovery window, and the supplied IAM policy includes tag-conditioned
DeleteSecreton the output prefix. A platform operator using another secret backend must verify itsPushSecretDelete support before enabling this workflow.
This repository intentionally contains no one-command destructive path. If the request is pruned without first being armed and ready, the default Retain behaviour applies and external resources are orphaned.
Topology and retention reference¶
This reference covers token lifetime ceilings and token-use subnet profiles, golden SLO handoff, bounded k6 and Synthetic Monitoring vending, explicit promotion ladders, creation-time retention classes, and the enforced SCIM exclusion. Both shared-stack access slices and stack-per-tenant deployments are intentional topologies. Product credentials use identity-bound bootstrap exchanges; provider readiness is not live product proof.
Token-use subnet profiles restrict where Fleet Management and telemetry policy tokens may be used from. They are not inbound Grafana stack filtering; no inbound stack IP-filtering mechanism was identified. The administrator service-account token has no equivalent conditions field.
Shared stacks centralize operations and isolate tenants through teams, folders, RBAC, datasource permissions and LBAC. Separate stacks provide independent lifecycles and complete departmental isolation, with duplicated configuration and stack-cap costs. Both are supported deliberately. Ladders require one organization and immutable region/rung identities. Free plans allow one stack and self-service paid plans three; larger ladders need a negotiated cap. Multi-stack datasources require one region and were capped at ten stacks in preview. Promotion direction is explicit and never causes a region replacement.
Retention classes select durable collector fan-out at creation; they do not set retention periods. Logs export forwards a rolling window of roughly seven to thirty days. Logs retention can be changed through a self-serve API in thirty-day multiples up to one year, while shorter periods require a support request; this Composition does not reconcile that API. Metrics and traces have no self-serve retention API, and no equivalent bulk export was found. Stack deletion is permanent, so decommission cannot recover telemetry that was never forwarded.
Adaptive products: deliberately out of scope¶
Adaptive Metrics is Grafana Cloud's largest cost lever, but this reference does not vend it. Adaptive Logs, Adaptive Traces, and Adaptive Profiles are also out of scope. This is a deliberate non-adoption decision, not an unsupported activation toggle hidden in the API: the stack request does not expose any adaptive-product configuration.
Use the Grafana Cloud UI and the applicable ticket-based service route for those products. The reversal cost is low because no request, credential, or composition here depends on this decision. The feasible future route is a dedicated provider/module once upstream packaging is ready; any future Adaptive Metrics design must choose either rulesets or individual rules as the sole owner per segment, because mixing them overwrites rules. That merge question is not applicable while the product remains out of scope.