Creating a plugin
Last updated
Last updated
Plugins enable Cortex users to pull data into their Cortex instance from any source, expose custom metrics, and customize the UI to match other internal tools. A plugin is an application that is embedded in Cortex. It uses a plugin proxy to send requests from the plugin to a third party.
You can use the Scaffolder in a Workflow to quickly spin up a Cortex plugin repository. The plugin code repository includes:
React + TypeScript
Linting and formatting via and
Testing via
Compilation to a single HTML file via
The Cortex React plugin package () pre-installed, which provides access to context, proxy usage, CSS variables for theme-based styling, and UI components.
Cortex offers a with examples using react-plugin-ui
.
The Cortex Plugin core package ().
If you created your plugin before April 2025 and your plugin is using components from plugin-core/components
, we have updated these components to utilize react-plugin-ui
. Please to migrate these components to the new design.
Users with the Edit plugins
permission can create a plugin.
If you do not have access to the feature in Cortex, please contact your Customer Success Manager for assistance.
In Cortex, navigate to Workflows.
In the upper right corner, click Create Workflow.
Click Blank Workflow.
Choose whether to Create a new repo or Open a pull request against an existing repo. Through the Scaffolder, Cortex can automatically set up a React + TypeScript repository for you with the basic setup for your plugin to make it easy to get started.
At the bottom of the Scaffolder side panel, click Save.
At the top of the page, click Save Workflow.
At the top of the page, click Run.
After saving your Workflow in the previous section, you need to run the Workflow and configure the plugin. The fields here differ depending on whether you chose to create a new repo or open a pull request.
At the top of the Workflow page, click Run.
Configure the plugin details:
Project name: Enter a name for the plugin.
License: Enter the license for your plugin.
Additional fields:
If you chose to create a new repo:
Repo org: Select an organization from the dropdown.
Repo name: Enter the name of the repo that will be created to hold this service.
Branch: Enter the name of the target branch that will be used as the default for the service.
Advanced configuration: Optionally, you can add encrypted GitHub secrets for other users in your organization to use during the service creation flow.
If you chose to open a pull request:
Repo: Enter the name of the repo the pull request will be opened against.
Branch to create: Enter the name of the branch where the generated code will be pushed.
Subdirectory: Enter the name of the subdirectory where the generated service will live.
At the bottom of the side panel, click Submit.
After you create the plugin from the Scaffolder template, you will be redirected to a status page for the plugin creation.
On the plugin status page after creating your plugin, click the button to open your repository.
Clone the repository locally.
Install dependencies via yarn
.
You can also use npm
commands if preferred.
Run yarn build
to generate a single HTML file representing your plugin (output at ./dist/ui.html
).
If you want to make any changes to the plugin, modify the code before running or re-running the build
command.
You will need this file in the next steps.
Configure the plugin:
Plugin name: Enter a display name for the plugin.
Identifier: Enter a unique identifier for the plugin.
Description: Enter a description of the plugin to help others understand its purpose.
Display icon: Select an icon that will be used when displaying this plugin across Cortex.
Minimum user role: Select the minimum user role required to be able to see this plugin. You can choose default or custom roles.
Note that you will not be able to delete a custom role if it is associated with a plugin.
Context: Select the context for your proxy:
Specific entity types: Select this option if you want to plugin to display in the sidebar of entity pages.
Both options: Select this option to have the ability to display the plugin in the main nav, on the dev homepage, and on entity pages.
In the "Code" section, upload the HTML file you generated from running yarn build
in the previous steps.
Dev mode: Toggle on to enable dev mode. When in dev mode, the preview for your HTML file uses code running at http://localhost:9000/ui.html. To run your plugin code from this location, use yarn dev
or npm run dev
from your Scaffolded plugin.
In the preview, iterate on any changes you might want to make to the plugin.
Click Save plugin.
Users with the Edit plugins
permission can edit plugins.
Optionally, you can preview your changes before implementing them:
In the row containing the plugin, click the 3 dots icon, then click Edit plugin.
Next to the "Code" section, enable the toggle next to Dev mode.
The preview will use code running at http://localhost:9000.
From your scaffolded plugin in command line, run yarn dev
.
View the preview on the Plugin editor page in Cortex.
In your text editor, open the cloned repo for your plugin.
After making changes and saving, run yarn build
.
Optionally, run yarn dev
to preview your changes in Cortex.
In the "Plugin code" section of the plugin editing page in Cortex, click Edit next to the file name. Select your newly-updated file.
At the bottom of the page, click Save plugin.
In the row containing the plugin, click the 3 dots icon.
The easiest way to access the plugin context is via the usePluginContext()
hook.
If you need to access the plugin context outside of a React component, you can use the CortexApi
class directly. The CortexAPI class exposed from @cortexapps/plugin-core
provides a method for accessing the context your plugin is running in, getContext()
.
You can access Cortex APIs using @cortexapps/plugin-core
’s CortexAPI
.
It is also possible to access non-Cortex APIs from your plugin. Because plugins are run in an iframe, typical fetch
requests often get blocked by the browser's enforcement of CORS. However, when using the Cortex-provided template, the browser fetch is shimmed to call CortexApi.proxyFetch
, a method for using Cortex as a proxy to make the request. For this reason, you should be able to use fetch()
as you typically would in a web application.
We add the following headers to each request made by Cortex. Use these headers to verify that the request is valid and originated from Cortex:
x-cortex-timestamp
This header uses the current timestamp in millis, and is used to prevent replay attacks. Cortex will sign the requests using the format <timestamp>.<body>
.
x-cortex-timestamp-only-signature-256
This header calculates the SHA256 signature using only the timestamp. Use this header in environments where the HTTP request body is unavailable due to platform limitations.
x-cortex-signature-256
This header uses the SHA256 algorithm. For security best practices, we recommend using this header rather than x-cortex-signature
.
x-cortex-signature
This header uses the SHA1 algorithm and exists for backward compatibility. SHA1 is considered unsafe and this signature should be considered deprecated.
Create a string with the value "$timestamp.$requestBody"
if the request body is non-null OR "$timestamp
" if the request body is null.
Calculate an HMAC using the SHA256 algorithm. Use the Secret you provided to Cortex as the key and the string from Step 1 as the payload.
Verify that the x-cortex-signature-256 matches the HMAC calculated in Step 2.
Cortex UI components are available for import from @cortexapps/react-plugin-ui
.
to your Workflow.
Configure the name, slug, and description for the Scaffolder step.
For the Scaffolder template dropdown, select Cortex Plugin.
For detailed configuration instructions, see the .
Go to the page in Cortex, and in the upper right corner, click Register plugin.
Associated proxy: If you have configured a , select the proxy to use for proxy fetches from this plugin.
Global: Select this option if you want to configure the plugin to appear in your main nav or as a tab on the .
To access authenticated external APIs, you can configure a plugin proxy to add request headers to requests matching a URL prefix. See for more information.
While viewing the , locate the plugin you want to share.
While viewing the , locate the plugin you want to share.
Click Share. A link is copied to your clipboard. You can share it with anyone who has access to view plugins in your Cortex workspace.
As of April 2025, all new plugins use , available in beta. This package enables Cortex plugin developers to create plugins that share the look and feel of Cortex in an iframe.
Cortex offers a with examples using react-plugin-ui
.
Prior to April 2025, plugins used . For existing plugins using plugin-core
, ensure that you have upgraded to or above to switch your components to the new design.
The react-plugin-ui
package includes CSS variables for theme-based styling. These styles will adjust to match the and will reflect your light or dark mode settings for your Cortex workspace. The styles are injected via an iframe postMessage
request, which is initiated by the Cortex CortexApi.pluginInit()
call.
If your plugin needs additional styling beyond what is available in react-plugin-ui
, you can also use the Cortex CSS API. See documentation for these variables in the .
See the for available API calls.
If your browser fetch is not getting shimmed properly, make sure that your @cortexapps/plugin-core
is up to date and you're using wrapping your app with <PluginProvider>
. See the for an example.
To calculate the signature (an HMAC):