Skip to main content

Workflow Reference

Feature Availability
Self-Hosted DataHub
DataHub Cloud

Note: Action Workflows is currently in Private Beta. To enable this feature, please reach out to the DataHub team.

This page is the exhaustive JSON syntax reference for an Action Workflow definition — the JSON document you submit as the input argument to the upsertActionWorkflow GraphQL mutation. For the conceptual introduction, see Action Workflows. For a worked end-to-end example, see the Workflow Tutorial.

The reference is organised top-down: the top-level definition first, then each primitive it composes, then the shared filter dialect, then the resolver catalogue, then the enum tables, then the GraphQL surface.

The launching entity. Throughout this reference, the launching entity is the entity from whose profile page the user launched the workflow — for example, the dataset on which the requester clicked the workflow's launch icon. Resolvers and filters that specify "source": "launching" begin their traversal from this entity.

How to Apply a Workflow Definition

A workflow definition is a JSON object submitted as the input argument to the upsertActionWorkflow GraphQL mutation. There are three common ways to apply one:

DataHub Python SDK

from datahub.ingestion.graph.client import DatahubClientConfig, DataHubGraph

graph = DataHubGraph(DatahubClientConfig(
server="https://your-datahub-instance.acryl.io/gms",
token="YOUR_ACCESS_TOKEN"
))

UPSERT = """
mutation upsertActionWorkflow($input: UpsertActionWorkflowInput!) {
upsertActionWorkflow(input: $input) { urn }
}
"""

with open("dataset-promotion-workflow.json") as f:
workflow_input = json.load(f)

result = graph.execute_graphql(UPSERT, variables={"input": workflow_input})
print(result["upsertActionWorkflow"]["urn"])

Raw GraphQL

curl -X POST https://your-datahub-instance.acryl.io/api/graphql \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d @- <<EOF
{
"query": "mutation upsertActionWorkflow(\$input: UpsertActionWorkflowInput!) { upsertActionWorkflow(input: \$input) { urn } }",
"variables": { "input": $(cat dataset-promotion-workflow.json) }
}
EOF

datahub CLI

There is no dedicated CLI subcommand for workflow upsert today. Wrap the JSON in a small Python or shell script that calls the Python SDK shown above. For most customers, GitOps-managed workflow JSONs are applied through a CI job that imports the SDK and calls upsertActionWorkflow directly.

Workflow Definition

The top-level shape of a workflow definition.

{
"urn": "urn:li:actionWorkflow:my-workflow",
"name": "My Workflow",
"description": "Free-form description shown to users.",
"category": "CUSTOM",
"customCategory": "GOVERNANCE",
"trigger": { ... },
"steps": [ ... ]
}
FieldTypeRequiredDescription
urnstringNoURN of an existing workflow to update. Omit to create a new workflow — DataHub generates a UUID-based URN.
namestringYesDisplay name of the workflow, shown in the entrypoint launch icon and the Task Center.
descriptionstringNoDescription shown to requesters before they launch the workflow.
categoryenumYesACCESS for access-request workflows, CUSTOM for everything else. See Categories.
customCategorystringIf category=CUSTOMFree-form string to group related custom workflows (e.g., GOVERNANCE, LIFECYCLE, PROPOSAL). Required when category is CUSTOM.
triggerTriggerYesHow and where requests are launched.
stepsarray of StepYesOrdered approval steps. Must contain at least one step.

Trigger

Describes how requests against this workflow are launched.

{
"trigger": {
"type": "FORM_SUBMITTED",
"form": { ... }
}
}
FieldTypeRequiredDescription
typeenumYesOnly FORM_SUBMITTED is supported today — the workflow is launched when a user submits a form.
formFormYesThe form the user fills in to start a request.

Form

Defines the entry points where the workflow's launch icon appears and the fields the requester fills in.

{
"form": {
"entityTypes": ["DATASET"],
"entrypoints": [ ... ],
"fields": [ ... ],
"excludedDefaultFields": ["EXPIRATION_DATE"]
}
}
FieldTypeRequiredDescription
entityTypesarray of EntityTypeNoEntity types whose profile pages can launch this workflow. Omit for context-free workflows that only launch from the HOME entrypoint.
entrypointsarray of EntrypointYesUI surfaces where the workflow's launch icon appears.
fieldsarray of FieldYesThe form fields the requester fills in. Submitted in order; fields with a filterCondition reveal themselves only when their condition holds.
excludedDefaultFieldsarray of DefaultFieldNoDefault fields that DataHub adds to every form. List the ones you want hidden — supported values: EXPIRATION_DATE, ADDITIONAL_NOTES.

Entrypoint

Where the workflow's launch icon appears in the UI.

{
"type": "ENTITY_PROFILE",
"label": "Promote to Certified",
"filter": {
"operator": "AND",
"filters": [
{
"field": "platform",
"values": ["urn:li:dataPlatform:snowflake"],
"condition": "EQUAL"
}
]
}
}
FieldTypeRequiredDescription
typeenumYesHOME (icon on the catalog home page) or ENTITY_PROFILE (icon on the profile pages of the entity types listed in the parent form's entityTypes).
labelstringYesUser-facing label on the launch icon.
filterFilterNoVisibility predicate evaluated against the launching entity's attributes. Only entities matching the filter see the launch icon. Only meaningful when type is ENTITY_PROFILE. Omit to show on every entity of the listed types.

Field

A single form field the requester fills in.

{
"id": "justification",
"name": "Reason for certification",
"description": "Minimum 100 characters.",
"valueType": "RICH_TEXT",
"allowedEntityTypes": ["CORP_USER"],
"allowedValues": [{ "stringValue": "30_DAYS" }],
"cardinality": "SINGLE",
"required": true,
"validation": { "pattern": "[\\s\\S]{100,}", "errorMessage": "..." },
"filterCondition": { ... },
"dynamicSource": { ... },
"valuesSource": { ... }
}
FieldTypeRequiredDescription
idstringYesWorkflow-local identifier. Other primitives reference this field via formField:<id> in filter expressions and field:<id> in resolver sources.
namestringYesDisplay label shown above the input control.
descriptionstringNoHelper text shown under the field.
valueTypeenumYesOne of STRING, RICH_TEXT, URN, DATE, NUMBER, BOOLEAN. See Value Types.
allowedEntityTypesarray of EntityTypeNoRequired when valueType is URN. Restricts the entity-picker to these types (e.g., ["CORP_USER"], ["GLOSSARY_TERM"]).
allowedValuesarray of PropertyValueNoFixed enumeration of allowed values. Renders as a dropdown.
cardinalityenumYesSINGLE (one value) or MULTIPLE (a list of values).
requiredbooleanNoDefaults to false. Required fields must be populated before the request can be submitted.
validationFieldValidationNoSubmit-time regex + length validation with a custom error message.
filterConditionFilterNoVisibility predicate. The field renders only when the filter evaluates to true. The filter can reference launching-entity attributes (tags, platform, etc.) and prior form-field values (via formField:<id>). See Field Visibility.
dynamicSourceDynamicSourceNoResolves the field's selectable options by traversing the catalog graph. URN-valued fields only.
valuesSourceValuesSourceNoSimpler alternative to dynamicSource for the special-case of "members of the current user's groups". URN-valued fields only.
conditionLegacyFieldConditionNoLegacy v1. Single-field-value condition for field visibility. Prefer filterCondition for new workflows.

Field Validation

Submit-time validation rule applied to a field's value.

{
"validation": {
"pattern": "[\\s\\S]{100,}",
"errorMessage": "Please describe at least 100 characters."
}
}
FieldTypeRequiredDescription
patternstringYesJava-flavoured regex pattern that the submitted value must match. Use length bounds ({100,}) for length validation.
errorMessagestringNoMessage rendered inline when validation fails. If omitted, a generic error message is shown.

Field Visibility

Field visibility is expressed with a filterCondition (Filter shape) that can mix:

  • Launching-entity attributestags, glossaryTerms, domain, platform, owners, subTypes, name, description, etc. See Filter Dialect for the full list.
  • Prior form-field values — referenced as formField:<field-id>. The value the requester has entered in the named field at the moment the form is being rendered.
{
"filterCondition": {
"operator": "AND",
"filters": [
{
"field": "glossaryTerms",
"values": ["urn:li:glossaryTerm:certification.gold"],
"condition": "CONTAIN"
},
{
"field": "formField:target_tier",
"values": ["urn:li:glossaryTerm:certification.gold"],
"condition": "EQUAL",
"negated": true
}
]
}
}

The field renders only when every filter predicate evaluates to true (operator: AND); use operator: OR for any-of semantics.

Legacy FieldCondition

The v1 single-field-value condition is still accepted by upsertActionWorkflow for back-compat but is deprecated. Prefer filterCondition.

{
"condition": {
"type": "SINGLE_FIELD_VALUE",
"singleFieldValueCondition": {
"field": "access_duration",
"values": ["PERMANENT"],
"condition": "EQUAL"
}
}
}
FieldTypeRequiredDescription
typeenumYesOnly SINGLE_FIELD_VALUE is supported.
singleFieldValueCondition.fieldstringYesWorkflow-local field id whose value is checked.
singleFieldValueCondition.valuesarrayYesValues the field is compared against.
singleFieldValueCondition.conditionenumNoEQUAL, CONTAIN, START_WITH, etc. Default: EQUAL.
singleFieldValueCondition.negatedbooleanNoInvert the predicate. Default: false.

DynamicSource

Resolves URN-valued field options or step actors by traversing the catalog graph at form-render time / step-open time.

{
"dynamicSource": {
"resolvers": [
{ "resolver": "OWNERS_OF", "source": "launching" },
{ "resolver": "DOMAIN_OWNERS_OF", "source": "field:co_signer_steward" }
],
"filter": {
"operator": "AND",
"filters": [ ... ]
}
}
}
FieldTypeRequiredDescription
resolversarray of ResolverYesOne or more resolvers. The engine evaluates each, then unions the returned URN sets. At least one resolver required.
filterFilterNoDestination-boundary predicate applied to the resolved URN set. Useful for narrowing the resolver output by platform, tag, or any indexed attribute. Multi-value EQUAL is treated as OR — only URNs in the value list pass.

Resolvers

Each resolver entry traverses one documented relationship in the catalog graph.

{ "resolver": "OWNERS_OF", "source": "launching" }
FieldTypeRequiredDescription
resolverstringYesResolver identifier from the Resolver Catalogue below.
sourcestringNoWhere to start the traversal. "launching" (default) starts at the launching entity. "field:<form-field-id>" starts at the URN the requester picked in a prior form field (the field must be URN-valued and submitted before this resolver evaluates). Required for chained / cross-field resolution.

Resolver Catalogue

The full set of built-in resolvers.

Actor-context resolvers — return user, group, and role URNs suitable for step actor resolution.

ResolverReturnsPurpose
OWNERS_OFusers, groupsOwners of the source entity.
DOMAIN_OWNERS_OFusers, groupsOwners of the source entity's domain.
DATA_PRODUCT_OWNERS_OFusers, groupsOwners of the source entity's data product.
APPLICATION_OWNERS_OFusers, groupsOwners of the source entity's application.
GLOSSARY_TERM_OWNERS_OFusers, groupsOwners of a glossary term linked to the source entity.
TAG_OWNERS_OFusers, groupsOwners of a tag linked to the source entity.
CONTAINER_OWNERS_OFusers, groupsOwners of the source entity's container.

Field-context resolvers (forward 1-hop) — return entity URNs reachable from the source entity along one documented edge.

ResolverReturnsPurpose
TAGS_OFtag URNsTags attached to the source entity.
GLOSSARY_TERMS_OFglossary term URNsGlossary terms attached to the source entity.
DOMAIN_OFdomain URNDomain of the source entity.
DATA_PRODUCT_OFdata product URN(s)Data products that contain the source entity.
APPLICATIONS_OFapplication URN(s)Applications associated with the source entity.
CONTAINER_OFcontainer URNContainer of the source entity.

Field-context resolvers (reverse 2-hop) — return entities that share a structural relationship with the source entity through an intermediate node.

ResolverReturnsPurpose
SIBLINGS_IN_DOMAINentity URNsOther entities in the same domain as the source entity.
SIBLINGS_IN_DATA_PRODUCTentity URNsOther entities in the same data product as the source entity.
SIBLINGS_IN_APPLICATIONentity URNsOther entities in the same application as the source entity.

Catalogue-wide resolver — returns every entity matching the parent field's allowedEntityTypes, useful when paired with a filter for fixed-URN allow-lists.

ResolverReturnsPurpose
ALL_ENTITIESentity URNsAll entities matching the parent field's allowedEntityTypes. Use with a filter (e.g., urn-EQUAL) for curated allow-lists.

ValuesSource

Simpler alternative to dynamicSource for the special case where a URN-valued field should be restricted to entities the current user already has a context-defined relationship with.

{
"valuesSource": {
"type": "CURRENT_USER_GROUPS",
"nameRegex": "^data-eng-.*"
}
}
FieldTypeRequiredDescription
typeenumYesOnly CURRENT_USER_GROUPS is supported today — the picker is restricted to groups the requesting user belongs to.
nameRegexstringNoJava-flavoured regex applied to the returned entities' name attribute as an additional narrowing filter.

Step

A single approval step in the decision graph.

{
"id": "data-owner-approval",
"type": "APPROVAL",
"description": "ALL_OF: every dataset owner must approve.",
"actors": { ... },
"condition": { ... },
"quorum": { "allOf": true }
}
FieldTypeRequiredDescription
idstringYesWorkflow-local step identifier. Referenced in audit history's stepId.
typeenumYesOnly APPROVAL is supported today.
descriptionstringNoDescription shown to reviewers when the step opens.
actorsStepActorsYesWho can decide on this step.
conditionFilterNoStep skip condition. If the condition evaluates to false when the step is about to open, the engine records a SKIPPED decision in the audit log and opens the next step automatically.
quorumQuorumNoHow many actors must approve for the step to advance. Default: { "anyOf": true }.

StepActors

Who can decide on a step.

{
"actors": {
"userUrns": ["urn:li:corpuser:alice"],
"groupUrns": ["urn:li:corpGroup:data-stewards"],
"roleUrns": ["urn:li:dataHubRole:Editor"],
"dynamicSource": {
"resolvers": [{ "resolver": "OWNERS_OF", "source": "launching" }]
},
"dynamicAssignment": { "type": "ENTITY_OWNERS" }
}
}
FieldTypeRequiredDescription
userUrnsarray of stringNoStatic user URNs. Defaults to an empty array when omitted.
groupUrnsarray of stringNoStatic group URNs. Any member of an assigned group can satisfy the slot. Defaults to an empty array when omitted.
roleUrnsarray of stringNoStatic role URNs. Any holder of an assigned role can satisfy the slot. Defaults to an empty array when omitted.
dynamicSourceDynamicSourceNoGraph-traversal resolver evaluated when the step opens. Returned URNs are added to the actor pool. Preferred over the legacy dynamicAssignment for new workflows.
dynamicAssignmentLegacyDynamicAssignmentNoLegacy v1. Named-resolver shortcut for the common owner-based assignments. Prefer dynamicSource.

At least one of userUrns, groupUrns, roleUrns, dynamicSource, or dynamicAssignment must produce at least one actor when the step opens. A step with no resolvable actors fails fast with QUORUM_UNREACHABLE. When a step uses only dynamic actors, omit userUrns, groupUrns, and roleUrns entirely — they default to empty arrays.

Legacy DynamicAssignment

The v1 named-resolver shortcut for owner-based assignments. Still accepted for back-compat. Prefer dynamicSource with the equivalent resolver name (OWNERS_OF, DOMAIN_OWNERS_OF, DATA_PRODUCT_OWNERS_OF) for new workflows — the dynamicSource form supports cross-field resolution and chained filters that this legacy shape does not.

{
"dynamicAssignment": {
"type": "ENTITY_OWNERS",
"ownershipTypeUrns": ["urn:li:ownershipType:__system__technical_owner"]
}
}
FieldTypeRequiredDescription
typeenumYesOne of ENTITY_OWNERS, ENTITY_DOMAIN_OWNERS, ENTITY_DATA_PRODUCT_OWNERS. Maps to OWNERS_OF / DOMAIN_OWNERS_OF / DATA_PRODUCT_OWNERS_OF in the v2 dialect.
ownershipTypeUrnsarray of stringNoFilter the resolved owners by these ownership type URNs (e.g., Technical Owner only). Omit to resolve owners of any ownership type.

Quorum

How many actors must approve for the step to advance.

The quorum field uses a union encoding — set exactly one of anyOf, allOf, or nofM.

{ "quorum": { "anyOf": true } }
{ "quorum": { "allOf": true } }
{ "quorum": { "nofM": { "n": 2 } } }
FieldTypeRequiredDescription
anyOfbooleanNoWhen true, any single approval advances the step. This is the default if no quorum is specified.
allOfbooleanNoWhen true, every actor or slot resolved at step-open time must approve. Group and role slots are expanded — any group member can satisfy that slot.
nofMobjectNoThreshold quorum. { "n": <count> } requires n distinct approvals out of the resolved actor pool. The n value must be ≥ 1 and ≤ the pool size at step-open time.

Filter Dialect

The shared filter shape used by entrypoint visibility, field visibility (filterCondition), step skip conditions (condition), and dynamicSource.filter.

{
"operator": "AND",
"filters": [
{
"field": "platform",
"values": ["urn:li:dataPlatform:snowflake"],
"condition": "EQUAL"
},
{
"field": "tags",
"values": ["urn:li:tag:pii"],
"condition": "CONTAIN",
"negated": true
}
]
}
FieldTypeRequiredDescription
operatorenumYesAND, OR, or NOT. Defines how the child predicates combine.
filtersarray of PredicateYesOne or more atomic predicates.

Predicate

A single field/value/operator/negation tuple.

FieldTypeRequiredDescription
fieldstringYesThe attribute to compare. See Field References for the supported attributes.
valuesarray of stringYesValues to compare against. Multi-value EQUAL / CONTAIN is treated as OR — a single match passes.
conditionenumNoComparison operator: EQUAL, CONTAIN, START_WITH, END_WITH, IN, EXISTS, GREATER_THAN, LESS_THAN, GREATER_THAN_OR_EQUAL_TO, LESS_THAN_OR_EQUAL_TO. Default: EQUAL.
negatedbooleanNoInvert the predicate. Default: false.

Field References

The field slot accepts two kinds of references:

Launching-entity attributes — properties of the entity from which the workflow was launched. Used in entrypoint visibility, step skip conditions, and the launching-entity half of field visibility conditions.

FieldDescription
urnThe entity's URN.
platformThe entity's platform URN (e.g., urn:li:dataPlatform:snowflake).
entityTypeThe entity's type (DATASET, DASHBOARD, etc.).
subTypesThe entity's sub-type values.
nameThe entity's display name.
descriptionThe entity's description.
tagsURNs of tags attached to the entity.
glossaryTermsURNs of glossary terms attached to the entity.
domainURN of the entity's domain.
dataProductURN(s) of data products that contain the entity.
applicationURN of the entity's application.
containerURN of the entity's container.
ownersURNs of users / groups that own the entity.

Form-field references — values the requester has entered in a prior form field. Used in field visibility conditions and step skip conditions. The referenced field must be defined earlier in the form's fields array.

Field referenceDescription
formField:<field-id>The current value of the named form field. For MULTIPLE-cardinality fields, the predicate evaluates against the array of values.

Categories

The high-level category of a workflow, used for grouping in the UI and for governance reporting.

ValuePurpose
ACCESSAccess-request workflows (the classical use case). Requests appear under the "Access" filter in the Task Center.
CUSTOMEverything else. Requires populating customCategory with a free-form string to identify the category (e.g., GOVERNANCE).

Value Types

Supported valueType values for form fields.

ValueCardinalityDescription
STRINGSINGLE / MULTIPLESingle-line text input. Pair with allowedValues for enum-style dropdowns.
RICH_TEXTSINGLEMulti-line rich-text input with formatting (bold, italic, links, etc.).
URNSINGLE / MULTIPLEEntity reference. Requires allowedEntityTypes. Optionally configure dynamicSource or valuesSource.
DATESINGLEDate/time, stored as epoch milliseconds.
NUMBERSINGLE / MULTIPLEInteger or floating-point number.
BOOLEANSINGLETrue/false toggle.

Entity Types

Entity-type identifiers used in entityTypes and allowedEntityTypes. Common values:

DATASET, DASHBOARD, CHART, DATA_PRODUCT, DATA_FLOW, DATA_JOB, DOMAIN, GLOSSARY_TERM, GLOSSARY_NODE, CORP_USER, CORP_GROUP, TAG, CONTAINER, ML_MODEL, ML_MODEL_GROUP, ML_FEATURE, ML_FEATURE_TABLE, APPLICATION.

The full set of entity types is defined by the catalog's entity registry — see the entityType aspect on the DataHub data model page for the canonical list.

Default Fields

Values for excludedDefaultFields. These are fields DataHub adds to every form by default; list them here to hide them on a specific workflow.

ValueDescription
EXPIRATION_DATEA date picker labelled "Expires on" added to every form.
ADDITIONAL_NOTESA free-form rich-text notes field added to every form.

Property Value

A single value in a field's allowedValues enumeration. Use the variant that matches the field's valueType.

{ "stringValue": "30_DAYS" }
{ "numberValue": 90 }
{ "urnValue": "urn:li:corpuser:alice" }
{ "booleanValue": true }
FieldTypeUse when
stringValuestringvalueType is STRING or RICH_TEXT.
numberValuenumbervalueType is NUMBER.
urnValuestringvalueType is URN. The URN of an allowed entity.
booleanValuebooleanvalueType is BOOLEAN.

GraphQL Surface

The mutations and queries used to manage workflow definitions and requests. Visit GraphiQL at https://your-datahub-instance.acryl.io/api/graphiql for the live, fully-typed schema.

Mutations

MutationPurpose
upsertActionWorkflow(input)Create or update a workflow definition. Returns the persisted workflow's URN. Every upsert produces a new immutable revision; in-flight requests continue against the revision they were launched under.
deleteActionWorkflow(urn)Delete a workflow definition. Returns an error if any requests referencing the workflow are still in PENDING state — resolve or cancel open requests first.
createActionWorkflowFormRequest(input)Submit a new workflow request. Returns the new request's URN.
reviewActionWorkflowFormRequest(input)Record an approval or rejection on a pending step. Returns an error if the step is already in a terminal state.
cancelActionWorkflowFormRequest(urn)Cancel an in-flight workflow request. Callable by the original requester on their own requests, or by an administrator with Manage Global Settings on any request.

Queries

QueryPurpose
actionWorkflow(urn)Fetch a single workflow definition by URN, including its current revision and all aspects.
listActionWorkflows(input)Page and filter the catalogue of workflow definitions by name, category, custom category, or launching entity type.
actionWorkflowFormRequest(urn)Fetch a single workflow request by URN, including its decisions, current step state, and audit history.
listActionWorkflowFormRequests(input)Page and filter workflow requests by status (PENDING, COMPLETED, CANCELLED), workflow URN, requester, or assignee.
listActionWorkflowsForEntityProfile(entityUrn)List the workflows whose entrypoints are visible for a given entity, accounting for entrypoint filters.