Production engineering guide for platform governance covering patterns, implementation strategies, and operational best practices.
Platform governance ensures that a platform evolves consistently across teams, environments, and time—aligning engineering practices, tooling, and policies without imposing rigid constraints. It matters when multiple teams consume shared services, when platform evolution outpaces ad hoc adoption, and when new contributors struggle to understand why things are built the way they are.
Platform governance is the process of establishing, communicating, and enforcing standards, policies, and workflows for a shared engineering platform. It determines who owns what, how changes are approved, and how services evolve in response to needs across the organisation. It is not a one-time setup but an ongoing practice, driven by recurring events—code reviews, release cycles, audits, and incident responses.
Governance applies to all platform artifacts: infrastructure, APIs, SDKs, developer onboarding flows, CI/CD pipelines, and configuration management. It ensures that platforms do not become islands of custom tooling, but integrated, predictable, and maintainable systems.
Platform policies define the rules for how teams interact with the platform. A policy is a document or configuration that answers: *What must be true of every service built on the platform?*
Policies are declared using a standard format: a YAML file, typically located at platform/policies/ in the platform repository. Each policy has a name, description, and a set of requirements.
name: Infrastructure
description: "All services must use the platform's standard infrastructure stack."
version: 1.2
applies_to:
- service
- component
- microservice
required:
- "All services must declare a service.yaml file in the root"
- "All services must use the platform's default Kubernetes configuration"
- "All services must define a monitoring profile in prometheus.yaml"
- "All services must use the platform's central logging schema"
enforcement:
- "CI job: platform-validate-infrastructure"
- "Automated PR comment with policy compliance score"
- "Failure if any required check is missing"
The platform-validate-infrastructure job runs on every PR and validates that the policy is satisfied. It uses kubectl to inspect the Deployment and Service manifests, yq to parse service.yaml, and curl to verify the presence of required fields in prometheus.yaml.
If a service fails to meet a policy, the CI job returns a structured report:
{
"policy": "Infrastructure",
"passed": false,
"issues": [
{
"check": "service.yaml exists",
"status": "failed",
"message": "Missing service.yaml in project root",
"details": {
"file_path": "service.yaml",
"expected": "/path/to/service.yaml",
"actual": "/path/to/missing-service.yaml"
}
},
{
"check": "prometheus.yaml defines monitoring profile",
"status": "warning",
"message": "Monitoring profile is missing required labels",
"details": {
"missing_labels": ["app", "team"],
"present_labels": ["env", "version"]
}
}
],
"score": 72
}
The PR is annotated with a comment: “Infrastructure policy compliance: 72/100. 2 issues found.” This feedback is immediate, actionable, and machine-readable.
Ownership is assigned through a platform/owners.yaml file, which defines roles, responsibilities, and contact points.
# platform/owners.yaml
platform:
name: "Core Platform"
email: "[email protected]"
slack: "#platform"
contact: "[email protected]"
lead: "[email protected]"
members:
- name: "Alice Chen"
email: "[email protected]"
role: "Platform Architect"
teams:
- "Infrastructure"
- "Developer Experience"
- name: "Bob Torres"
email: "[email protected]"
role: "Platform Engineer"
teams:
- "CI/CD"
- "Observability"
responsibilities:
- "Review all platform policy changes"
- "Maintain platform release schedule"
- "Manage platform onboarding materials"
- "Respond to platform incidents within 2 hours"
Ownership is not static. When a team submits a PR to change a platform policy, the system checks owners.yaml to identify the responsible owners. A GitHub action triggers a review request to all members listed under platform.members, with a template that includes:
If no response is received within 48 hours, the system sends a reminder via email and Slack, using curl to POST to a Slack webhook:
curl -X POST \
-H "Content-Type: application/json" \
-d '{
"text": "🔔 Review overdue: Platform policy change #123",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "A review for *Infrastructure policy update* is overdue. Please review the changes before the 72-hour window closes."
}
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": "Review PR"
},
"url": "https://github.com/platform/policies/pull/123"
},
{
"type": "button",
"text": {
"type": "plain_text",
"text": "Comment"
},
"url": "https://github.com/platform/policies/pull/123#issuecomment-12345"
}
]
}
]
}' \
https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX
Compliance is enforced through a platform-wide audit process. Every quarter, the platform team runs a compliance sweep to verify that all services adhere to the current policies.
The audit is driven by a script that:
service.yaml and kubernetes/ directory.jq and yq queries.#!/bin/bash
# scripts/audit-compliance.sh
set -euo pipefail
# Get all services from registry
services=$(psql -t -A -c "SELECT name FROM services WHERE active = true")
for service in $services; do
echo "Auditing $service..."
# Fetch service metadata
curl -s "https://registry.company.com/v1/services/$service" \
| jq -r '.config.service.yaml' \
> /tmp/$service/service.yaml
# Copy Kubernetes manifests
mkdir -p /tmp/$service/k8s
curl -s "https://registry.company.com/v1/services/$service/manifests" \
| tar -xzf - -C /tmp/$service/k8s
# Validate infrastructure policy
if ! yq eval '.service_type == "microservice"' /tmp/$service/service.yaml; then
echo "❌ $service: Missing service_type field"
fi
# Check for required labels in prometheus.yaml
if ! yq eval 'has("labels") and .labels.app and .labels.team' /tmp/$service/prometheus.yaml; then
echo "⚠️ $service: Missing required labels in prometheus.yaml"
fi
# Validate CI pipeline
if ! grep -q "platform-validate-infrastructure" /tmp/$service/.github/workflows/main.yml; then
echo "🚨 $service: CI pipeline missing platform validation step"
fi
done
The script produces a CSV report:
service,compliance_score,issues
payments-service,95,"Missing app label in prometheus.yaml, CI step missing"
auth-service,80,"service_type missing, labels incomplete"
user-service,100,"All checks passed"
This report is published to a platform dashboard and used to identify teams that are lagging behind. Teams with compliance below 85 are flagged for a quarterly platform review meeting.
When a platform evolves—new features, deprecations, breaking changes—governance ensures smooth transitions.
Each evolution is documented as a platform release, which includes:
platform/releases/v1.2.yaml# platform/releases/v1.2.yaml
version: 1.2
date: 2023-10-15
title: "Enhanced Observability and Service Discovery"
description: "Introduces new tracing and service discovery features."
breaking_changes:
- "Service manifests now require a `discovery` section"
- "The `service.yaml` schema has changed: `team` is now `owner.team`"
- "Prometheus metrics must include `service_id` label"
deprecations:
- "service.yaml.team (deprecated in 1.0, now removed in 1.2)"
- "kubernetes/configmap.yaml (to be removed in 1.3)"
- "logging.schema.json (replaced by platform-logging.schema.json)"
migration_guide:
- "Update service.yaml: move `team` to `owner.team`"
- "Add `discovery` section to service.yaml"
- "Update prometheus.yaml to include `service_id` label"
- "Run platform-migrate-1.2 command"
The platform-migrate-1.2 command is a CLI tool that applies common migration steps:
platform-migrate-1.2 --path ./services/payments-service --dry-run
It outputs:
Migrating payments-service to v1.2:
- [✓] Found service.yaml
- [✓] Found prometheus.yaml
- [✓] Found kubernetes/ directory
- [ ] Updating owner.team from team
- [ ] Adding discovery section to service.yaml
- [ ] Adding service_id label to prometheus.yaml
- [ ] Updating logging schema reference
Summary:
3 changes applied
1 file modified
2 new files created
1 config entry added
When the command is run with --apply, it modifies files in place and commits them with a standard Git message:
platform: migrate to v1.2
- Moved team → owner.team in service.yaml
- Added discovery section
- Added service_id label to prometheus.yaml
- Updated logging schema path
This migration tool is used by teams during onboarding, release planning, and incident response. It ensures that platform evolution is not just announced, but enacted.
Platform governance fails silently when policies are ignored, ownership is unclear, and compliance is untracked.
Common failure modes:
service.yaml. The CI job passes, but the service lacks required labels, and observability breaks in production.service_id label is missing, and tracing spans are incomplete.These failures are diagnosed using a governance dashboard, a simple psql query that pulls together audit reports, PR review timelines, and release compliance:
SELECT
s.name AS service,
p.title AS policy,
p.status AS compliance,
r.created_at AS review_due,
COALESCE(r.reviewed_at, '2023-01-01') AS last_reviewed,
(r.created_at - r.reviewed_at) AS days_to_review
FROM services s
JOIN service_policy_compliance sc ON s.id = sc.service_id
JOIN policies p ON sc.policy_id = p.id
LEFT JOIN review_requests r ON p.id = r.policy_id
WHERE p.version = '1.2'
AND s.last_deployed < '2023-09-01'
AND r.reviewed_at IS NULL
ORDER BY days_to_review DESC;
This query identifies services that are behind on policy review and highlights teams with long review cycles.
Platform governance is not a set of documents but a set of recurring, automated, and visible processes. It is maintained through:
Governance is effective when it is visible, repeatable, and self-correcting. When a team opens a PR and sees a policy score, a list of owners, and a migration guide, they are not just consuming a platform—they are participating in its governance.
This page was rewritten on 18 October 2026. It replaced a templated version that was not specific to its own title. How these pages are written and checked. If anything here is wrong, tell us at [email protected] and we will correct it.
We use cookies for analytics (Google Analytics) and advertising (Google AdSense) to improve your experience and support free content. Privacy Policy