If the integrations that Cortex provides out-of-the-box isn't sufficient, you can easily extend the metadata using custom data.
Custom data allows you to include additional information about all the entities in your catalog, to be used for:
- Querying with CQL
- Applying Scorecards rules to data from internal tools
- Viewing extra details in the Catalog
Custom data can be added to entities programmatically via a REST API or through defined manually in a Catalog Descriptor.
The Catalog contains lots of useful metadata about entities, including ownership and data from integrations. However, you may have your own custom fields that you want to include that would make exploring the catalog easier.
These can include things like:
- Which AWS zones is this deployed in?
- What databases does the entity consume?
- When was the last successful CI run?
If the answers to these questions fit a pre-enumerated list, consider using groups. Custom data for cataloging makes the most sense when the data is more freeform/flexible.
The data in the Catalog can then be queried against through our CQL-powered Query Builder, or even to quickly view information directly in the service or resource homepage.
You may want to write Scorecard rules that apply to information outside of data provided by our out-of-the-box integrations. For example, you may want to write rules that depend on data from your own internal tools, or vulnerability scan data that happens as part of a CI pipeline.
Using the custom data API to push data into Cortex is a great way to extend your Scorecards. You can even
send in entire JSON payloads, and use
jq to process them in a Scorecard or even as an input to a custom
as a Scorecard rule.
Defining custom data
There are a few ways you can add custom data to an entity, including the Catalog Descriptor, a
POST REST API, and a simple webhook.
The simplest way to describe information in the yaml is to define an object.
description: Scan runs nightly
Custom data can be of any type, including scalars (strings, numbers, booleans), objects, and lists.
If you want to add a description to one of your pieces of data, just define it with the
value key set explicitly.
value: the actual value for the key
description: this is the description
description: Scan runs nightly
The request body is the following, in JSON format. See API Docs for authentication details.
|The key for custom data
|object (string, boolean, number, list, ...)
|Value to set for the key
|An optional description for the data to be displayed in the dashboard.
If a key has already been set through the Catalog Descriptor, an API call will NOT overwrite the existing value. Instead, it will simply return the existing value - you'll notice the
source value in the response body is
To explicitly overwrite values set in the YAML file, use the
force=true flag as a query param. If you find yourself using the
force flag, you should likely remove the field from the YAML file since it is no longer the source of truth, or update the value in the
cortex.yaml file instead.
Read more about the Source Hierarchy.
If you're trying to upload multiple keys for a single entity, or many keys for many entities, you can use the bulk upload endpoint.
Just PUT data in the following format to
"<another tag>": [
In some cases, you may not have obvious access to the entity tag, or ability to add authentication headers. For example, if you're unable to connect Cortex directly to your SonarQube instance, you may want to dump SonarQube webhook data into Cortex as custom data.
"Custom data Webhooks" give you the ability to create unique URLs that you can use to directly POST arbitrary JSON payloads without auth or an explicit entity tag in the URL. Instead, you can tell Cortex how to process the payload to map it to an entity (e.g., the payload may include a
data.tag field that corresponds to the entity tag).
To create a Webhook URL:
- Visit Settings → Custom Integrations
- Create a new Custom Integration
- Give this webhook a human-readable name, like
- Define a
jqexpression that Cortex will use to extract the entity tag from the payload, for example
.data.entity.tag. If the tag that Cortex extracts from the payload is not exactly equal to the entity tag, the endpoint will throw a 400.
- Add a
keyunder which the data will be stored for entities, which is the same as the
keywhen using the Entity Descriptor or REST API.
- Save the integration, and copy the provided webhook URL.
- cURL any JSON your heart desires to this URL!
The data can be used exactly the same way as custom data defined through the Entity Descriptor or the API.
Changing the mappings for services
In the case where the webhook payload does not contain a value that maps to the exact entity tag (for example, a SonarQube payload where
the project key in SonarQube is
com.my.project but the
x-cortex-tag of the entity is
my-project), you can tell Cortex alternative
mappings to look up when processing payloads.
When processing a payload, Cortex takes the output of the jq command in step 3 above, and first looks up if there's an entity with that value as a tag. If no such entity exists, we check whether an entity has registered the value as an alternative mapping, and if so, attach the payload to that entity.
Data source hierarchy
What happens when you try to define the same
key from multiple sources? There's a hierarchy that's applied:
- The Catalog Descriptor is the source of truth. If a key is defined there, the API or webhooks cannot override the key.
- The API and Webhook approaches are at the same level and can override each other.
You can override keys defined in the YAML by adding a
force=true param when using the API, but there's no guarantee – when the Catalog Descriptor is eventually re-processed, the data provided via the API will be overwritten.