Skip to main content


Although you can easily update the catalog directly through the Cortex UI, switching to a GitOps approach provides a few benefits.

The GitOps approach involves disabling the UI editor, and making all changes to your catalog data through an entity descriptor file and syncing the changes to this file using our official Git integrations, or programmatically using our API.

Using a GitOps model with the entity descriptor checked into git provides a few benefits:

  • The metadata is version controlled
  • The repository where your code lives is also the source of truth for information
  • You always own the data
When should I switch to GitOps?

We don't recommend switching to GitOps for your organization until Cortex has been broadly rolled out. We suggest allowing developers to experiment with Cortex through the UI, and having a line-in-the-sand for a GitOps cutover.

Built-in integrations

All of our official Git integrations support automatically parsing your entity descriptor files, which allows you to make the switch in less than 5 minutes.

Disable UI editing to enable GitOps

None of the GitOps integrations outlined here will work if in-app UI editing is enabled.

To enable the GitOps style approach, you'll have to disable UI editing in Settings → Entities -> GitOps.

This is to ensure consistency - any changes made through the UI would otherwise be overwritten by changes to cortex.yaml in the git repo.


Regardless of which integration you're using, there are a few similarities.

  1. Cortex will only check for files in the default branch, e.g. master, unless otherwise specified. We default to master if there is no default branch defined.
  2. Cortex does not delete Scorecards if the corresponding scorecard YAML is deleted. You can enable the auto archival of entities through GitOps in Settings -> Entities -> General -> Enable auto archiving of entities
  3. If using GitHub or GitLab, the service or resource YAML descriptor can be located anywhere in the repository as long as the file is named cortex.yaml or cortex.yml.
  4. We recommend putting the service or resource descriptor files in the root of the repository or in the appropriate .cortex/catalog folder
  5. Domain, team, and Scorecard definitions must be in the .cortex/domains, .cortex/teams, or .cortex/scorecards folders, respectively.
  6. For Bitbucket, Bitbucket Server, or Azure DevOps, you MUST place your descriptors in the appropriate .cortex/ subdirectory (note: for unique cases it is possible to work around) this.
  7. You can define any number of services, resources, domains, and Scorecards within the same repository. Here is an example structure:
└── .cortex
├── catalog
│ ├── database.yml
│ ├── s3-bucket.yml
│ ├── auth-service.yml
│ └── billing-service.yml
├── domains
│ ├── billing-domain.yml
│ └── health-domain.yml
├── teams
│ ├── eng-team.yml
│ └── sre-team.yml
└── scorecards
│ ├── service-readiness.yml
│ └── security.yml


Official app

We offer an official GitHub app that comes pre-configured for GitOps with Cortex.

The GitHub app has a built in linter – if the entity descriptor file is invalid, the GitHub app will comment on the PR with the outstanding issues!


If you do not wish to use the official app, or prefer to integrate with GitHub using a personal access token, you can manually add a webhook to your GitHub organization.

  1. Once you've added a PAT under Settings → GitHub, you'll see an option to set up a webhook by adding a secret.
  2. Add a secret passphrase and take note of it. This passphrase will be used by GitHub to prove that the webhook event is valid.
  3. Once you've added the secret, it'll give you a unique webhook URL.
  4. Follow the instructions from GitHub on adding an org-level webhook. When creating this webhook, GitHub will ask for a URL (created in step 3) and a secret (the one created in step 1). Set the content type to application/json.
  5. Start using GitOps!


Due to the lack of native support for applications, GitLab support requires setting up a webhook so that Cortex is notified when the entity descriptor is modified.

As a prerequisite, first follow the GitLab integration setup instructions. Once you've connected Cortex with GitLab:

  1. Create a secret token for your GitLab webhook from the Cortex dashboard (Settings → GitLab)
  2. In GitLab, set up a System Hook (recommended) or a project hook.
  3. If you are only using one GitLab account, use as the URL. Otherwise, if you are opting into multi account support, use{alias} as the URL. alias should be replaced with what is noted under alias in the entity descriptor.
  4. Enable Push events for the webhook
  5. Add the secret token you created in step 1 to the webhook configuration. This token allows us to verify your webhook events.
  6. Start using GitOps!


Bitbucket Cloud

Install the Bitbucket app from Settings → Bitbucket.


You'll need to enable development mode to use the Cortex app. You can find this setting at {your_workspace} /workspace/settings/addon-management/.

No other configuration needed!

Bitbucket Server

In order to use GitOps with Bitbucket Server, you can manually add a webhook.

  1. Navigate to Settings -> Bitbucket and ensure your Bitbucket Server integration is set up and connected per the Bitbucket Server integration instructions.
  2. After saving the integration, enter a secret token for your Bitbucket Server webhook
  3. After saving the secret, then click the Create a new webhook button and copy the unique webhook URL (for non-default configuration, the suffix /{alias} should be added to the generated URL).
  4. Follow the Bitbucket Server instructions for adding a project-level or repository-level webhook. Make sure you check the repository push event type and use the secret from step 2 and the URL from step 3.

Azure DevOps


In order to use GitOps with Azure DevOps you can manually add a webhook.

  1. Navigate to Settings -> Azure DevOps and ensure your Azure DevOps integration is set up and connected.
  2. Click the Create a new webhook button and copy the unique webhook URL.
  3. Follow the instructions from Azure on adding a webhook. Make sure you set your event type to be Code pushed and use the URL generated in step 2.

API upload

If you have a custom integration needs, you can use our API to upload the YAML file.

  1. Create an API key on the Cortex dashboard (Settings → API Keys)
  2. Upload it as a file to with the API token set as a header: Authorization: Bearer <token>.

For example:

--data-binary @cortex.yaml
-H "Content-Type: application/openapi"
-H "Authorization: Bearer <token>"

We suggest uploading this file as part of your CI/CD process so that the documentation never goes stale.

Dry run

This API also accepts two optional parameters:

  • dryRun(boolean): whether or not to persist the changes being uploaded. This API can be used to lint your YAML file, or to check for breaking API changes as part of a CI process. Defaults to false.
  • githubPullRequest(int, ID of the pull request): in conjunction with the dryRun flag, Cortex can optionally comment on a pull request with breaking changes, if any are detected. This requires GitHub to be connected to cortex. See GitHub integration details.


--data-binary @cortex.yaml
-H "Content-Type: application/openapi"
-H "Authorization: Bearer <token>"


A monorepo is defined as using one Git repository for multiple services. When using GitOps with monorepos you can use a cortex.yaml or cortex.yml file per subdirectory representing that service.

Details on the relevant configuration used are covered on the respective integration pages for GitHub, GitLab, and Azure DevOps. Bitbucket requires special considerations when using monorepos.