콘텐츠로 이동

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

IssueCauseSolution
Service not appearing in catalogcortex.yaml not on default branchMerge cortex.yaml to main/master branch
Scorecard showing 0 scoreRules not matching entity typeVerify scorecard filter matches entity type
On-call data not syncingPagerDuty integration misconfiguredVerify API key and service ID mapping
Custom metadata not appearingSchema not definedCreate custom metadata schema before using fields
GitHub data staleWebhook not configuredSet up GitHub webhook for real-time sync
Dependency graph incompleteDependencies not declaredAdd x-cortex-dependencies to cortex.yaml
Scorecard evaluation slowToo many rules or entitiesOptimize rule expressions; reduce scorecard scope
API returning 403API key scope insufficientGenerate 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'