Backstage catalog entity spec (CCE export)
Reference for YAML emitted by cce --format backstage. For install, commands, and workflows, see the Backstage Software Catalog guide.
CCE outputs multi-document YAML (--- separated):
- One
Componentfor the scanned repository. - Zero or more
APIentities for discovered OpenAPI/Swagger documents. - One
Resourceper deduplicated(provider, resource)entitlement pair from the scan.
Component
| Field | Source | Required |
|---|---|---|
apiVersion |
Constant backstage.io/v1alpha1 |
yes |
kind |
Component |
yes |
metadata.name |
--backstage-name, .cce/backstage.yaml, or project/folder slug |
yes |
metadata.namespace |
--backstage-namespace or default default |
no |
metadata.description |
CLI, file, or README discovery | no |
metadata.tags |
File/CLI tags + optional --backstage-language |
no |
metadata.annotations |
See Annotations | no |
metadata.links |
README link when Source URL + README exist | no |
spec.type |
Default service |
yes |
spec.lifecycle |
Default production; experimental when --classification is dormant or junk |
yes |
spec.owner |
CLI, file, mapped discovery, or unknown |
yes |
spec.system |
--backstage-system or file |
no |
spec.providesApis |
Discovered API entity names | no |
spec.dependsOn |
Deduped Resource refs: resource:<namespace>/<resource-name> |
no |
API
| Field | Source | Required |
|---|---|---|
apiVersion |
backstage.io/v1alpha1 |
yes |
kind |
API |
yes |
metadata.name |
Normalized OpenAPI info.title (collision-safe with parent dir) |
yes |
metadata.title |
OpenAPI info.title |
no |
metadata.description |
OpenAPI info.description or title |
no |
metadata.namespace |
Same as Component | no |
spec.type |
openapi |
yes |
spec.lifecycle |
Same as Component | yes |
spec.owner |
Same as Component owner | yes |
spec.system |
Same as Component system when set | no |
spec.definition |
Inline file contents when ≤ 2 MiB (self-contained for central catalogs); larger specs are skipped with a warning | yes* |
*Required on emitted API entities. Oversized specs are not emitted.
Only files named openapi|swagger with .yaml/.yml/.json extensions are considered. Root must include openapi or swagger. Generated/vendor trees are skipped.
Resource
| Field | Source | Required |
|---|---|---|
apiVersion |
backstage.io/v1alpha1 |
yes |
kind |
Resource |
yes |
metadata.name |
Normalized {provider}-{resource} (kebab-case) |
yes |
metadata.description |
Auto: "{PROVIDER} {resource} dependency discovered by CCE" |
no |
metadata.tags |
Component tags + provider + resource | no |
metadata.namespace |
Same as Component | no |
spec.type |
Heuristic from resource name (see below) | yes |
spec.owner |
Same as Component owner | yes |
Relations are written on the Component (dependsOn). CCE does not emit Resource dependencyOf edges (Backstage synthesizes the reverse).
Resource spec.type heuristics
| Pattern in resource name | spec.type |
|---|---|
queue, sqs, kafka |
queue |
cache, redis |
cache |
db, rds, sql |
database |
s3, storage, bucket |
storage |
| (default) | {provider-lowercase}-resource (e.g. aws-resource) |
Annotations
| Key | Set when |
|---|---|
cce.stackgen.com/source-url |
--source-url or git remote discovery |
backstage.io/source-location |
When Source URL is known (url:<repo>/) |
backstage.io/techdocs-ref |
Valid MkDocs layout discovered (URL uses remote default branch when known) |
cce.stackgen.com/scm |
--scm or inferred from remote |
github.com/project-slug |
GitHub SCM + project slug |
gitlab.com/project-slug |
GitLab SCM + project slug |
cce.stackgen.com/language |
--backstage-language |
cce.stackgen.com/last-commit |
--last-commit or repository HEAD via go-git |
cce.stackgen.com/owner-inference |
Owner came from mapped discovery (codeowners or git-history) |
Deduplication rules
- Entitlements are grouped by case-normalized
(provider, resource)from the CCE scan. - Each unique pair becomes one Backstage
Resourceand onedependsOnentry on the Component. - Operation-level detail (file, line, method) stays in the JSON report, not in catalog YAML.
- API titles that collide are disambiguated with the parent directory segment.
Repo-local config file
Path: <scan-folder>/.cce/backstage.yaml (override with --backstage-config).
name: my-service
description: Human-readable summary
owner: group:default/team-name
type: service
lifecycle: production
system: optional-system
namespace: default
tags:
- tag-one
owner_mappings:
"@acme/team-name": group:default/team-name
"Jane Doe": group:default/team-name
Precedence: CLI flags > file > discovery > defaults.
Classification → lifecycle
--classification |
Default lifecycle when not set elsewhere |
|---|---|
live-service |
production |
dormant |
experimental |
junk |
experimental |
Horizontal catalog repo layout (example)
catalog/
components/
acme-checkout-api.yaml # CCE backstage output (Component + API + Resource docs)
systems/
commerce.yaml # optional System entity (hand-authored)
CCE emits Component, API, and Resource documents. System, Domain, User, and Group entities remain org-authored or ingested from IdP/SCM.
Validation checklist
Before opening a catalog PR:
- [ ]
metadata.nameis unique in the target namespace. - [ ]
spec.ownermatches a registered Backstage group/user (or mappings are configured). - [ ]
providesApis/ API entities look correct for the service. - [ ] TechDocs annotation is present only when MkDocs layout is valid.
- [ ]
dependsOnlist is reviewable (not dominated by test-fixture noise). - [ ] SCM / source-location annotations match the canonical clone URL.
- [ ] JSON entitlement report archived for audit if required.
Related
- Changelog — release history
- Backstage Software Catalog guide — install, commands, and local workflows
- Example config —
.cce/backstage.yamltemplate in repo