catalog-info.yaml

The single source of truth for how the builder deploys your service. Every deploy reads this file. The builder generates Dockerfiles, provisions databases, configures OAuth, registers routes, and sets up DNS — all from this one file.

Minimal Working Example

apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: my-svc
  description: My API service
  annotations:
    insureco.io/framework: express
spec:
  type: service
  lifecycle: production
  owner: my-org    # your org slug from Bio-ID JWT

Current Version (0.5.0)

apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: my-svc
  annotations:
    insureco.io/framework: express          # REQUIRED
    insureco.io/catalog-version: "0.5.0"   # required for spec.tests
    insureco.io/pod-tier: nano             # nano|small|medium|large|xlarge
    insureco.io/health-endpoint: /health   # REQUIRED (0.2.0+)
spec:
  type: service
  lifecycle: production
  owner: my-org                            # REQUIRED (0.2.0+), not 'unknown'

  routes:
    - path: /api/my-svc/data
      methods: [GET, POST]
      auth: required
      gas: 1

  databases:
    - type: mongodb    # → MONGODB_URI
    - type: redis      # → REDIS_URL

  internalDependencies:
    - service: septor
    - service: iec-wallet
      port: 3000

  tests:
    smoke:
      - path: /health
        expect: 200

Framework Types

FrameworkStart CommandPortHealth
expressnode dist/index.js3000/health
nextjsnpm start3000/api/health
hononode dist/index.js3000/health
fastifynode dist/index.js3000/health
workernode dist/worker.js3000none
staticnginx80/health

Dependencies: Which Format to Use

Key rule: internalDependencies for everything without Bio-ID scopes. dependencies only when the target service defines explicit scope grants.

# Use internalDependencies for platform services and most internal services:
spec:
  internalDependencies:
    - service: septor       # → SEPTOR_URL
    - service: iec-wallet   # → IEC_WALLET_URL
    - service: iec-queue    # → IEC_QUEUE_URL

# Use dependencies ONLY for services with Bio-ID scope grants:
spec:
  dependencies:
    - service: raterspot
      transport: direct           # injects RATERSPOT_URL
      scopes: [raterspot:rate]   # REQUIRED, cannot be empty

Common mistake: using dependencies with scopes: [] — that is a validation error. Common mistake: using transport: gateway expecting a URL env var — gateway does not inject a URL.

Routes

routes:
  - path: /api/my-svc/screen
    methods: [POST]
    auth: required    # required | none | service | public
    gas: 5           # tokens per successful call. 0=free. omit=default(1)

Auth values:

  • required — valid user JWT required (Janus verifies)
  • service — service-to-service JWT required
  • public — no auth, but still metered
  • none — no auth, not metered (use for health checks)

Queues and Schedules

spec:
  queues:
    - name: process-claim
      endpoint: /internal/jobs/process-claim
      concurrency: 5
      retries: 3
      retryDelayMs: 5000
      timeoutMs: 30000

  schedules:
    - name: nightly-sync
      cron: "0 2 * * *"
      endpoint: /internal/cron/nightly-sync
      timezone: America/Denver
      timeoutMs: 60000

Queue and schedule endpoints must NOT be listed under routes:. They are internal-only.

All Annotations

annotations:
  insureco.io/framework: express           # REQUIRED
  insureco.io/catalog-version: "0.5.0"    # required for spec.tests
  insureco.io/node-version: "20"          # default: 20
  insureco.io/pod-tier: nano              # default: nano
  insureco.io/health-endpoint: /health    # REQUIRED (0.2.0+)
  insureco.io/port: "3000"               # default: 3000
  insureco.io/build-command: npm run build
  insureco.io/start-command: node dist/index.js
  insureco.io/output-dir: dist
  insureco.io/openapi: openapi.yaml       # enables auto-generated UI tile

Monorepo / Subdirectory Services

If your service lives in a subdirectory (e.g., web/ inside a monorepo), add .iec.yaml at the repo root:

# .iec.yaml (repo root)
appPath: web

The builder then reads catalog-info.yaml from web/catalog-info.yaml, uses web/ as the build context, and resolves Dockerfile and Helm chart paths relative to web/. No other changes needed.

See the .iec.yaml — Builder Config reference for all supported fields.

Key Facts

  • metadata.name becomes your hostname: my-svc.tawa.insureco.io
  • You do NOT need a Dockerfile — the builder generates one from your framework
  • Pod tier defaults to nano — start here, upgrade when you have data
  • Adding a database to an existing service: just add it to catalog-info.yaml and redeploy
  • Redeploying does NOT touch your data — databases are persistent
  • For monorepos: add .iec.yaml at the repo root with appPath: <subdir> — see .iec.yaml reference

Last updated: February 28, 2026