Manifests
Manifests are YAML files that declaratively define entity metadata. They are the recommended way to manage entities at scale, following a GitOps-style workflow where your service catalog is defined alongside your code.
For an exhaustive field-by-field schema reference, see Manifest Model.
File Location
Section titled “File Location”Place manifests in your repository at:
.shoehorn/manifest.ymlShoehorn also discovers manifests matching these patterns (configurable):
.shoehorn/**/*.yml.shoehorn/**/*.yamlcatalog-info.yaml(Backstage compatibility)
Manifest Structure
Section titled “Manifest Structure”schemaVersion: 1
service: id: payment-api # Required, kebab-case unique identifier name: Payment API # Required, display name type: service # Required, entity type tier: gold # Optional, service tier
description: | Handles payment processing, refunds, and transaction management.
owner: # Required (except for catalog-source type) - type: team id: payments-team - type: user id: alice@company.com
lifecycle: production # Optional
tags: # Optional - payments - financial - critical
links: # Optional - name: Repository url: https://github.com/company/payment-api icon: GitHub - name: Grafana Dashboard url: https://grafana.company.com/d/payments icon: Grafana
relations: # Optional - type: depends_on target: service:stripe-integration - type: depends_on target: database:payments-db - type: publishes_to target: topic:payment-events - type: part_of target: system:financial
interfaces: # Optional http: baseUrl: https://api.company.com/v1/payments openapi: docs/openapi.yaml auth: type: oauth2 grpc: package: com.company.payments proto: proto/payments.proto services: - PaymentService - RefundService
integrations: # Optional changelog: path: CHANGELOG.md runbooks: - title: Payment Processing Incident path: docs/runbooks/payment-incident.md severity: critical - title: Database Migration path: docs/runbooks/db-migration.md severity: high licenses: - title: Stripe API vendor: Stripe expires: "2025-12-31" cost: "$2000/year"
docs: # Optional readme: path: README.md
extras: # Optional - type: slackchannel target: "#payments-team"Field Reference
Section titled “Field Reference”service (Required)
Section titled “service (Required)”| Field | Required | Description |
|---|---|---|
id | Yes | Unique kebab-case identifier. Must match ^[a-z0-9]+(-[a-z0-9]+)*$ |
name | Yes | Human-readable display name |
type | Yes | Entity type (see Entities) |
tier | No | Service tier: platinum, gold, silver, bronze |
members | No | Array of member emails (for team type) |
At least one owner is required (except for catalog-source type).
| Field | Description |
|---|---|
type | Owner type: team, user, productOwner, designer, stakeholder, support, manager |
id | Team slug, user email, or entity reference |
relations
Section titled “relations”| Field | Required | Description |
|---|---|---|
type | Yes | Relation type (see below) |
target | Yes | Target in format <type>:<identifier> |
role | No | Role in the relationship |
notes | No | Additional context |
Relation types: depends_on, publishes_to, consumes_api, provides_api, deployed_to, calls, reads_from, writes_to, subscribes_to, uses, via, part_of
Target types: service, database, topic, team, channel, link, oncall, system, resource
| Field | Required | Description |
|---|---|---|
name | Yes | Link display name |
url | Yes | URL (must be http:// or https://) |
icon | No | Icon name (see Annotations Reference for supported icons) |
interfaces
Section titled “interfaces”interfaces: http: baseUrl: "https://api.example.com/v1" # HTTP base URL openapi: "docs/openapi.yaml" # OpenAPI spec path or URL auth: type: "oauth2" # oauth2, apikey, none graphql: endpoint: "/graphql" # GraphQL endpoint schema: "schema.graphql" # Schema file grpc: package: "com.example.service" # gRPC package proto: "proto/service.proto" # Proto file path or URL services: # gRPC service names - "UserService" - "AuthService"integrations
Section titled “integrations”changelog
Section titled “changelog”integrations: changelog: path: "CHANGELOG.md" # Path relative to repository rootrunbooks
Section titled “runbooks”integrations: runbooks: - title: "Incident Response" # Required path: "docs/runbook.md" # Optional, file path severity: "critical" # Optional: critical, high, medium, lowlicenses
Section titled “licenses”integrations: licenses: - title: "Stripe API" # Required vendor: "Stripe" # Optional purchased: "2024-01-15" # Optional, ISO date expires: "2025-01-14" # Optional, ISO date seats: 1 # Optional, minimum 1 cost: "$2000/year" # Optional contract: "STRIPE-2024" # Optional notes: "Auto-renewal" # Optionalextras
Section titled “extras”| Field | Required | Description |
|---|---|---|
type | Yes | slackchannel, teamLinks, custom, catalog-discovery-url, catalog-discovery-file |
target | Yes | Value for the extra (e.g., #channel-name) |
Backstage Compatibility
Section titled “Backstage Compatibility”Shoehorn can import Backstage catalog-info.yaml files. The following Backstage kinds are supported:
| Backstage Kind | Shoehorn Type |
|---|---|
Component | service |
API | api |
Resource | resource |
System | system |
Domain | domain |
Group / User | team |
Template | library |
Location | catalog-source |
Backstage fields are automatically mapped:
metadata.name->service.idmetadata.title->service.namespec.owner->ownerspec.lifecycle->lifecyclemetadata.tags->tagsmetadata.links->linksspec.dependsOn->relations[type=depends_on]spec.consumesApis->relations[type=consumes_api]spec.providesApis->relations[type=provides_api]
Validating Manifests
Section titled “Validating Manifests”Via API
Section titled “Via API”curl -X POST https://shoehorn.example.com/api/v1/manifest/validate \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/yaml" \ --data-binary @.shoehorn/manifest.ymlVia the UI
Section titled “Via the UI”Navigate to Catalog > Validate Manifest and paste or upload your YAML.
See Manifest Validation for details on what the validator checks.
Analyzing Manifests
Section titled “Analyzing Manifests”The analyze endpoint provides quality scoring and recommendations:
curl -X POST https://shoehorn.example.com/api/v1/manifest/analyze \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/yaml" \ --data-binary @.shoehorn/manifest.ymlThe response includes:
- Quality score (0-100)
- Category scores: Documentation, Relationships, Interfaces, Metadata
- Issues: Warnings and errors
- Recommendations: Suggested improvements
See Also
Section titled “See Also”- Manifest Model - Exhaustive schema reference
- Manifest Validation - Validation rules and common errors