Cortex.io Cheat Sheet
Overview
Cortex.io (now part of the Cortex internal developer portal) is a platform for building and maintaining an internal service catalog with automated scorecards that measure engineering standards compliance. It aggregates metadata from Git repositories, CI/CD pipelines, cloud infrastructure, monitoring tools, and on-call systems to create a comprehensive view of every service in your organization, including ownership, dependencies, documentation status, and operational readiness.
Scorecards are the core differentiator — they allow engineering leadership to define measurable quality standards (like “every service must have an on-call rotation,” “test coverage above 80%,” or “no critical vulnerabilities”) and automatically evaluate every service against those standards. This data-driven approach to engineering excellence provides visibility into technical debt, promotes accountability, and helps organizations scale their engineering practices consistently across hundreds of microservices.
Installation
API Setup
# Set API credentials
export CORTEX_API_KEY="your-api-key"
export CORTEX_API="https://api.cortex.dev/catalog"
# Verify connectivity
curl -s "$CORTEX_API/entities" \
-H "Authorization: Bearer $CORTEX_API_KEY" | jq '.entities | length'
Cortex CLI
# Install Cortex CLI
npm install -g @cortexapps/cli
# Configure
cortex config set --api-key "$CORTEX_API_KEY"
# Verify
cortex catalog list --limit 5
Git Integration (cortex.yaml)
# Add cortex.yaml to your repository root
# This is the primary way to register services
cat > cortex.yaml << 'EOF'
openapi: 3.0.1
info:
title: Payment Service
description: Handles payment processing and billing
x-cortex-tag: payment-service
x-cortex-type: service
x-cortex-team: payments-team
x-cortex-owners:
- type: group
name: payments-team
- type: email
email: payments-oncall@company.com
x-cortex-git:
github:
repository: org/payment-service
x-cortex-oncall:
pagerduty:
id: PSERVICE1
type: SERVICE
x-cortex-dashboards:
embeds:
- type: grafana
url: https://grafana.internal/d/payments
x-cortex-custom-metadata:
tier: "0"
compliance: ["SOC2", "PCI"]
language: go
framework: gin
deploy-target: kubernetes
EOF
Core Commands — Catalog Management
Managing Entities
# List all entities
curl -s "$CORTEX_API/entities" \
-H "Authorization: Bearer $CORTEX_API_KEY" | jq '.entities[] | {tag, type, name}'
# Get specific entity
curl -s "$CORTEX_API/entities/payment-service" \
-H "Authorization: Bearer $CORTEX_API_KEY" | jq '.'
# Create/update entity via API
curl -X PUT "$CORTEX_API/entities/payment-service" \
-H "Authorization: Bearer $CORTEX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"tag": "payment-service",
"title": "Payment Service",
"type": "service",
"description": "Handles all payment processing",
"owners": [
{"type": "group", "name": "payments-team"}
],
"metadata": {
"tier": "0",
"language": "go",
"deploy-target": "kubernetes"
}
}'
# Delete entity
curl -X DELETE "$CORTEX_API/entities/old-deprecated-service" \
-H "Authorization: Bearer $CORTEX_API_KEY"
# Search entities
curl -s "$CORTEX_API/entities?type=service&owner=payments-team" \
-H "Authorization: Bearer $CORTEX_API_KEY" | jq '.entities[] | .tag'
# Get entity dependencies
curl -s "$CORTEX_API/entities/payment-service/dependencies" \
-H "Authorization: Bearer $CORTEX_API_KEY"
Registering Services via cortex.yaml
# cortex.yaml — Full example with all fields
openapi: 3.0.1
info:
title: Checkout API
description: |
Customer-facing checkout API that orchestrates payment,
inventory, and shipping workflows.
x-cortex-tag: checkout-api
x-cortex-type: service
x-cortex-team: commerce-team
x-cortex-domain: commerce
x-cortex-owners:
- type: group
name: commerce-team
- type: slack
channel: "#commerce-oncall"
x-cortex-git:
github:
repository: org/checkout-api
basepath: /
x-cortex-issues:
jira:
project: CHECKOUT
x-cortex-oncall:
pagerduty:
id: CHECKOUT_SVC
type: SERVICE
x-cortex-apm:
datadog:
monitors:
- 12345678
newrelic:
applicationId: 98765432
x-cortex-slos:
- target: 99.9
metric: availability
provider: datadog
x-cortex-dashboards:
embeds:
- type: grafana
url: https://grafana.internal/d/checkout
- type: datadog
url: https://app.datadoghq.com/dash/12345
x-cortex-links:
- name: Documentation
type: documentation
url: https://docs.internal/checkout-api
- name: Runbook
type: runbook
url: https://runbooks.internal/checkout
- name: Architecture Diagram
type: documentation
url: https://docs.internal/checkout-architecture
x-cortex-dependencies:
- tag: payment-service
method: POST
path: /v1/payments
description: Process payments
- tag: inventory-service
method: GET
path: /v1/inventory/check
- tag: shipping-service
x-cortex-custom-metadata:
tier: "1"
compliance: ["SOC2", "PCI"]
language: typescript
framework: nestjs
deploy-target: kubernetes
data-classification: sensitive
Core Commands — Scorecards
Managing Scorecards
# List all scorecards
curl -s "$CORTEX_API/scorecards" \
-H "Authorization: Bearer $CORTEX_API_KEY" | jq '.scorecards[] | {tag, name}'
# Get scorecard details
curl -s "$CORTEX_API/scorecards/production-readiness" \
-H "Authorization: Bearer $CORTEX_API_KEY" | jq '.'
# Get scorecard scores for all services
curl -s "$CORTEX_API/scorecards/production-readiness/scores" \
-H "Authorization: Bearer $CORTEX_API_KEY" | jq '.scores[] | {entity: .entityTag, score: .score, level: .level}'
# Get specific entity's scorecard scores
curl -s "$CORTEX_API/entities/payment-service/scorecards" \
-H "Authorization: Bearer $CORTEX_API_KEY" | jq '.scores[] | {scorecard: .scorecardTag, score, level}'
# Create a scorecard
curl -X POST "$CORTEX_API/scorecards" \
-H "Authorization: Bearer $CORTEX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"tag": "production-readiness",
"name": "Production Readiness",
"description": "Measures if a service meets production standards",
"filter": {
"type": "service"
},
"levels": [
{"name": "Gold", "color": "#FFD700", "rank": 1},
{"name": "Silver", "color": "#C0C0C0", "rank": 2},
{"name": "Bronze", "color": "#CD7F32", "rank": 3},
{"name": "Not Ready", "color": "#FF0000", "rank": 4}
],
"rules": [
{
"title": "Has an owner",
"expression": "entity.owners.length > 0",
"weight": 10,
"level": "Not Ready",
"description": "Every service must have at least one owner"
},
{
"title": "Has on-call rotation",
"expression": "oncall != null",
"weight": 20,
"level": "Bronze"
},
{
"title": "Has documentation",
"expression": "entity.links.some(l => l.type == 'documentation')",
"weight": 10,
"level": "Bronze"
},
{
"title": "Has runbook",
"expression": "entity.links.some(l => l.type == 'runbook')",
"weight": 15,
"level": "Silver"
},
{
"title": "Has monitoring dashboard",
"expression": "entity.dashboards.length > 0",
"weight": 15,
"level": "Silver"
},
{
"title": "Has SLOs defined",
"expression": "entity.slos.length > 0",
"weight": 20,
"level": "Gold"
},
{
"title": "No critical vulnerabilities",
"expression": "vulnerabilities.critical == 0",
"weight": 10,
"level": "Gold"
}
]
}'
Scorecard Reports
# Export scorecard scores as CSV
curl -s "$CORTEX_API/scorecards/production-readiness/scores" \
-H "Authorization: Bearer $CORTEX_API_KEY" \
| jq -r '.scores[] | [.entityTag, .score, .level] | @csv'
# Get failing rules for a service
curl -s "$CORTEX_API/entities/checkout-api/scorecards/production-readiness" \
-H "Authorization: Bearer $CORTEX_API_KEY" \
| jq '.rules[] | select(.passing == false) | {title, description}'
# Get team-level scorecard summary
curl -s "$CORTEX_API/scorecards/production-readiness/scores?groupBy=team" \
-H "Authorization: Bearer $CORTEX_API_KEY"
Configuration
Integration Configuration
# Configure integrations in Cortex settings
# PagerDuty Integration
integrations:
pagerduty:
api_key: "pagerduty-api-key"
auto_discover: true
# GitHub Integration
github:
token: "github-pat-token"
organization: "your-org"
auto_discover_repos: true
# Datadog Integration
datadog:
api_key: "datadog-api-key"
app_key: "datadog-app-key"
site: "datadoghq.com"
# Jira Integration
jira:
url: "https://company.atlassian.net"
email: "service-account@company.com"
api_token: "jira-api-token"
# SonarQube Integration
sonarqube:
url: "https://sonar.internal.company.com"
token: "sonarqube-token"
Custom Metadata Schema
# Define custom metadata fields
curl -X PUT "$CORTEX_API/custom-data/schemas" \
-H "Authorization: Bearer $CORTEX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"fields": [
{"key": "tier", "type": "string", "enum": ["0", "1", "2", "3"], "required": true},
{"key": "compliance", "type": "array", "items": {"type": "string"}},
{"key": "language", "type": "string"},
{"key": "framework", "type": "string"},
{"key": "deploy-target", "type": "string", "enum": ["kubernetes", "ecs", "lambda", "vm"]},
{"key": "data-classification", "type": "string", "enum": ["public", "internal", "sensitive", "restricted"]}
]
}'
Advanced Usage
Bulk Operations
# Bulk import entities from JSON
curl -X POST "$CORTEX_API/entities/bulk" \
-H "Authorization: Bearer $CORTEX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"entities": [
{"tag": "service-a", "title": "Service A", "type": "service", "owners": [{"type": "group", "name": "team-alpha"}]},
{"tag": "service-b", "title": "Service B", "type": "service", "owners": [{"type": "group", "name": "team-beta"}]}
]
}'
# Export full catalog
curl -s "$CORTEX_API/entities?includeMetadata=true&includeScores=true" \
-H "Authorization: Bearer $CORTEX_API_KEY" > catalog-export.json
Automation and CI/CD Integration
# GitHub Actions — auto-register service on merge
name: Register in Cortex
on:
push:
branches: [main]
paths: ['cortex.yaml']
jobs:
register:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Register service
run: |
curl -X PUT "$CORTEX_API/entities/from-yaml" \
-H "Authorization: Bearer ${{ secrets.CORTEX_API_KEY }}" \
-H "Content-Type: application/yaml" \
--data-binary @cortex.yaml
Scorecard Notifications
# Set up Slack notifications for scorecard changes
curl -X POST "$CORTEX_API/scorecards/production-readiness/notifications" \
-H "Authorization: Bearer $CORTEX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "slack",
"channel": "#engineering-standards",
"triggers": [
{"event": "level_changed", "direction": "down"},
{"event": "score_below", "threshold": 50}
]
}'
Troubleshooting
| Issue | Cause | Solution |
|---|---|---|
| Service not appearing in catalog | cortex.yaml not on default branch | Merge cortex.yaml to main/master branch |
| Scorecard showing 0 score | Rules not matching entity type | Verify scorecard filter matches entity type |
| On-call data not syncing | PagerDuty integration misconfigured | Verify API key and service ID mapping |
| Custom metadata not appearing | Schema not defined | Create custom metadata schema before using fields |
| GitHub data stale | Webhook not configured | Set up GitHub webhook for real-time sync |
| Dependency graph incomplete | Dependencies not declared | Add x-cortex-dependencies to cortex.yaml |
| Scorecard evaluation slow | Too many rules or entities | Optimize rule expressions; reduce scorecard scope |
| API returning 403 | API key scope insufficient | Generate key with required scopes (read/write) |
# Debug: validate cortex.yaml
cortex catalog validate -f cortex.yaml
# Check entity registration status
curl -s "$CORTEX_API/entities/my-service/audit-log" \
-H "Authorization: Bearer $CORTEX_API_KEY" | jq '.[0]'
# Verify integration status
curl -s "$CORTEX_API/integrations/status" \
-H "Authorization: Bearer $CORTEX_API_KEY" | jq '.[] | {name, status, lastSync}'
# List entities missing owners
curl -s "$CORTEX_API/entities?hasOwner=false" \
-H "Authorization: Bearer $CORTEX_API_KEY" | jq '.entities[] | .tag'