- A single Python decorator,
@registry.register from typing import Annotatedfrom typing_extensions import Doc
Quick start
- Add a Python file to your custom registry package.
- Register one async function with
@registry.register(...). - Define typed inputs, read secrets with
secrets.get(...), and return JSON-serializable data.
What to define
- Use
tools.<integration>for the namespace. - Set
default_title,description,display_group,doc_url, andnamespacein@registry.register(...). - Define action inputs with type hints and
Field(..., description=...). - Define required credentials with
RegistrySecret(...)and pass them insecrets=[...]. - Read secret values with
secrets.get(...). - Return plain dicts, lists, strings, numbers, or booleans.
Declaring secret types
By default, secrets arecustom (arbitrary key-value). If your action requires an SSH key, mTLS certificate, or CA certificate, set secret_type so the credentials UI renders the correct form.
Examples
secret_type uses snake_case everywhere — Python declarations, the API, and the UI all use the same values (ssh_key, ca_cert, mtls, custom).
Use the same ${{ SECRETS... }} syntax as workflow actions.
Custom secrets (API keys, SSH, mTLS, CA bundles, and so on):
OAuth
OAuth expressions use the provider’s exact ID, not its display name.- Built-in providers use stable lowercase IDs assigned by Tracecat, with
underscores between words, such as
slack,google_drive, andmicrosoft_sentinel. - Custom providers use an ID derived from the provider name, or from the
requested ID when you create one through the API. Tracecat slugifies it with
underscores and prepends
custom_.My Security APIbecomescustom_my_security_api. If that ID is already used for the same grant type, Tracecat appends_1,_2, and so on.
_oauth to the exact provider ID for the secret name. For the key,
uppercase the complete provider ID, preserve its underscores and any numeric
suffix, then append _USER_TOKEN for authorization_code or _SERVICE_TOKEN
for client_credentials.
google_drive authorization-code provider and a custom
custom_my_security_api client-credentials provider resolve as:
Tracecat refreshes expiring authorization-code tokens when the provider
issued a refresh token, and reacquires client-credentials tokens with the
stored client credentials. The expression resolves only to the current
access-token string, which may be a JWT or an opaque token, not the refresh
token.
Python UDFs
Declare credentials in@registry.register(..., secrets=[...]).
RegistrySecret: static keys; setsecret_typetossh_key,mtls, orca_certwhen needed (secret types). Optional:optional,optional_keys.RegistryOAuthSecret: declares a dependency on an existing OAuth integration. Pass theprovider_idandgrant_typethat match the integration in your workspace (a mismatch — for example declaringauthorization_codewhen the integration usesclient_credentials— will not resolve).
secrets.get("<KEY>") (key only, e.g. GOOGLE_DRIVE_USER_TOKEN), not a SECRETS. path.
YAML
Underdefinition, set a secrets list (same validator as Python).
Custom (optional secret_type for structured secrets):
provider_id and grant_type must match an integration already configured in your workspace. Use ${{ SECRETS.<provider_id>_oauth.<TOKEN_KEY> }} in args. Set optional: true on an OAuth entry when it is not always required.
Example providers
Seeintegrations/google_drive.py and integrations/slack_sdk.py for UDFs that use OAuth credentials. See tracecat_registry/core/ssh.py for an ssh_key secret example.
For YAML templates, see microsoft_teams/send_message.yml (authorization_code), google_docs/create_document.yml (client_credentials), and microsoft_sentinel/.../get_alert_rule_template.yml (optional dual grant). See templates/tools/exa/search.yml for a simple API key template.
For the full list of built-in provider IDs, see tracecat/integrations/providers/__init__.py.