Connector configuration
Triggers
Triggers define which resource events activate the connector. Each trigger specifies:
-
resources– The resource types to match. -
events– The event types to match. -
stepType– The type of step to execute (for publish connectors). -
steps– One or more step configurations to execute in order.
Supported resources
The following resource types can activate a trigger.
| Resource | Description |
|---|---|
|
|
Triggered when a project is created, updated, or deleted. |
|
|
Triggered when an asset is created, updated, or deleted. |
|
|
Triggered when a file within an asset is processed. |
|
|
Triggered when a derived file (produced by a previous connector or processing job) is created. This is the primary mechanism for chaining connectors. A Deadline Cloud job that produces a |
Supported events
The following events can activate a trigger.
| Event | Description |
|---|---|
|
|
A resource is created. |
|
|
A resource is updated. |
|
|
A resource is deleted. |
|
|
A file is added to or updated within an asset. |
|
|
All files in an asset have finished uploading and the asset is ready. |
|
|
A derivation or processing job for a file has completed. Use this to chain connectors — for example, triggering a publish after a Deadline Cloud job finishes. |
|
|
Manually triggered by a user from the Spatial Data Portal or via the API. |
A single trigger can match multiple resources and events. For example, a trigger with "resources": ["asset"], "events": ["create", "update"] fires on both asset creation and update.
Ordering connectors with dependsOn
When one connector’s work must complete before another connector runs, use dependsOn on the downstream trigger. This orders connector execution within the same lifecycle context — the set of work that a single upstream event triggers.
"triggers": [ { "description": "Publish to catalog after quality analysis completes", "resources": ["asset"], "events": ["derivationComplete"], "dependsOn": ["<quality-analysis-connector-id>"], "steps": [{ ... }] } ]
dependsOn takes a list of connector IDs. SDMA evaluates the status of each listed connector within the current lifecycle before dispatching:
-
If all upstream connectors have succeeded (or were not applicable because no trigger matched), the downstream connector is queued normally.
-
If any upstream connector has failed, the downstream connector is marked as
DEPENDENCY_BLOCKEDand does not execute. -
If upstream connectors are still running, the downstream connector waits until they reach a terminal state.
Rules:
-
Dependencies apply only within a single lifecycle context. A connector does not wait on unrelated invocations from other events.
-
Upstream connectors must be in the same library and must share at least one template association with the dependent connector.
-
dependsOnis for ordering between connectors, not a general-purpose workflow mechanism. For ordering within a single connector, use multi-step triggers.
For most compositions, you do not need dependsOn. Connectors compose naturally through the asset record. One connector produces a derived file or updates metadata, and another connector triggers on that lifecycle event. Use dependsOn only when you need explicit ordering within the same lifecycle context that the asset record alone does not provide.
Output routing
When a step completes — whether a REST call, a Lambda invocation, or a Deadline Cloud job — you can route the results back into the asset record. Use an output block to do this. Output routing is how connectors write results back to SDMA as governed metadata, derived files, or both.
Output routing works uniformly across all step types. The same output block works on REST steps, Lambda steps, and Deadline Cloud jobs. For Deadline Cloud, place the output block inside the deadlineJob configuration on the trigger (see Create and transform content with AWS Deadline Cloud). The vocabulary is identical regardless of which step type produced the result.
The output block supports the following routing targets:
| Target | Description |
|---|---|
|
|
Writes response fields to asset or file metadata attributes. Contains a |
|
|
Ingests files that the step wrote to S3, attaching them as derived files on the asset. Each entry specifies a |
|
|
Ingests files as top-level files on the asset (without a derived-from relationship). Each entry specifies a |
Routing metadata with fieldMappings
The metadataAttributes target uses fieldMappings to control which response fields to write and where to write them. Each mapping has a source (a field in the step response) and a target (an SDMA metadata path). Use :type suffixes on targets to store values as typed metadata (see Type coercion).
"output": { "metadataAttributes": { "fieldMappings": [ { "source": "overallScore", "target": "asset.metadataAttributes.qualityScore:number" }, { "source": "classification", "target": "asset.metadataAttributes.classification" }, { "source": "processedAt", "target": "asset.metadataAttributes.lastProcessed:date" } ] } }
Mappings with asset.
targets write to asset-level metadata. Mappings with file. targets write to file-level metadata on the triggering file. An optional filter on metadataAttributes narrows which files' attributes the connector processes.
Combining metadata and derived files
A single output block can route to multiple targets. This is the canonical pattern when a step produces both summary metadata (for search and display) and detailed output files (for downstream processing or review).
"output": { "metadataAttributes": { "fieldMappings": [ { "source": "score", "target": "asset.metadataAttributes.qualityScore:number" }, { "source": "status", "target": "asset.metadataAttributes.analysisStatus" } ] }, "derivedFiles": [ { "filter": { "fileExtensionFilter": ".json" } }, { "filter": { "fileExtensionFilter": ".glb" }, "preview": true } ] }
In this example, the step writes quality scores into asset metadata and ingests .json detail files and .glb preview files as derived files. The preview: true flag marks matched files as preview content in the Spatial Data Portal.
Any trigger that declares an output block makes the connector asset-content-scoped, which means you must approve it through the template authorization chain.
Field mappings
Field mappings transform resource metadata into the format expected by the external system. Each mapping specifies a source field from the resource metadata and a target field name for the output.
"fieldMappings": [ { "source": "project.projectId", "target": "projectId" }, { "source": "asset.assetName", "target": "name" }, { "source": "geoJson:asset.geoLocation", "target": "bbox" } ]
Source field prefixes
Source fields must use a resource prefix or a special prefix:
| Prefix | Description |
|---|---|
|
|
Project metadata field (for example, |
|
|
Asset metadata field (for example, |
|
|
File metadata field (for example, |
|
|
System-generated field (for example, |
|
|
Extracts a GeoJSON bounding box from a location field (for example, |
|
|
Uses a literal string value (for example, |
Note
Flat field references like projectId are not allowed. Always use the fully qualified form project.projectId to avoid ambiguity.
Array iteration
Field mappings support iterating over arrays using the [*] syntax. For example, to map each file in an asset:
{ "source": "asset.files[*].path", "target": "assets[${file.path}].title" }
This creates one output entry per file, using the file path as the key.
You can define field mappings at the connector level as a default and override them per step when different events require different output shapes.
Payload fields
For publish connectors, the payload.fields array selects which mapped field names to include in the output. If you omit it, the connector includes all mapped fields. This gives you explicit control over what data the connector sends to the external system.
"payload": { "format": "json", "fields": ["projectId", "assetId", "name"] }
Variable substitution
Many configuration fields support ${variable} substitution using resource metadata values. You can use variable substitution in:
-
Step paths (for example, REST API paths, S3 object keys)
-
Request body templates (the
bodyfield on a step — an alternative to field-mapping-based payload construction) -
Query parameters
-
Security configuration fields (for example,
${secret.username}) -
Field mapping sources
-
Output routing field mappings
Examples:
-
assets/${project.projectId}/${asset.assetId}.jsonresolves toassets/proj-abc123/asset-def456.json -
${asset.metadataAttributes.customField}resolves to the value of a custom metadata attribute -
${secret.password}resolves to a value from the referenced Secrets Manager secret
Type coercion
When you need to store a value as a specific metadata type, append a :type suffix to the target path or to an expression inside ${…}:
-
On a target path — declares the intended metadata type:
asset.metadataAttributes.surveyDate:date,asset.metadataAttributes.score:number,asset.metadataAttributes.approved:boolean. -
Inside an expression — coerces the expression result before mapping:
${response.site_codes:numberList},${response.tags:stringList}.
Supported type suffixes: string, number, boolean, date, stringList, numberList.
Example:
{ "source": "response.survey_date", "target": "asset.metadataAttributes.surveyDate:date" }
{ "source": "${response.site_codes:numberList}", "target": "asset.metadataAttributes.siteCodes:numberList" }
Without a type suffix, SDMA stores values as strings. Use type coercion when the external system returns values that you want to search or filter as numbers, dates, booleans, or lists in SDMA
Intermediate state with $temp variables
In multi-step triggers, steps often need to pass values to subsequent steps — for example, capturing an ID from a creation response and using it in a follow-up request. The $temp.* namespace provides this intermediate state.
Use responseFieldMapping on a step to capture response values into $temp.* variables:
"steps": [ { "description": "Create external record", "method": "POST", "path": "/api/records", "body": { "name": "${asset.assetName}" }, "responseFieldMapping": [ { "source": "id", "target": "$temp.recordId" }, { "source": "status", "target": "$temp.status" } ] }, { "description": "Upload file content to the new record", "method": "PUT", "path": "/api/records/${$temp.recordId}/content", "bodyFromFile": { "contentType": "application/octet-stream" } } ]
$temp.* variables apply only to a single trigger execution. SDMA does not share them across triggers or across connectors. Each trigger invocation starts with an empty $temp namespace.
$temp.* variables work anywhere that ${variable} substitution is supported: step paths, query parameters, body templates, and field mapping sources.
Security configuration
Connectors authenticate with external systems using a securityConfig block. SDMA supports the following authentication types:
| Type | Description |
|---|---|
|
|
Assumes an IAM role to access AWS resources. Requires |
|
|
Sends an API key in a header, query parameter, or cookie. Requires |
|
|
Fetches a token from an OAuth/token endpoint and includes it in requests. Requires |
|
|
Sends HTTP Basic authentication credentials. Requires |
IAM role naming
IAM roles used by connectors must follow a naming convention:
-
Publish connectors – Role name must start with
SpatialDataManagementContentPublisher- -
Derive connectors – Role name must start with
SpatialDataManagementContentDerivation-
SDMA validates the role name prefix and tests role assumption when you create the connector. If the role cannot be assumed, connector creation fails with a validation error.
Examples
The following examples show different authentication configurations.
IAM role assumption:
"securityConfig": { "type": "AssumeRole", "assumeRoleArn": "arn:aws:iam::<ACCOUNT_ID>:role/SpatialDataManagementContentPublisher-MyRole" }
API key in a header:
"securityConfig": { "type": "ApiKey", "apiKeyLocation": "header", "headerName": "X-API-Key", "secretArn": "arn:aws:secretsmanager:<REGION>:<ACCOUNT_ID>:secret:<SECRET_NAME>", "assumeRoleArn": "arn:aws:iam::<ACCOUNT_ID>:role/SpatialDataManagementContentPublisher-MyRole" }
Token-based authentication (OAuth 2.0):
"securityConfig": { "type": "TokenAuth", "tokenEndpoint": "https://auth.example.com/oauth/token", "tokenMethod": "POST", "headerName": "Authorization", "tokenPrefix": "Bearer", "tokenResponseField": "access_token", "tokenRequestBody": { "grant_type": "client_credentials" }, "secretArn": "arn:aws:secretsmanager:<REGION>:<ACCOUNT_ID>:secret:<SECRET_NAME>", "assumeRoleArn": "arn:aws:iam::<ACCOUNT_ID>:role/SpatialDataManagementContentPublisher-MyRole" }
Connected resources
Some connectors need to associate a project with an external resource — for example, a STAC collection or an external project identifier. The optional resources block in the connector configuration defines how SDMA discovers, validates, and displays these external resources.
Each resource type (project, asset, file) can define three sub-configurations:
| Sub-config | Purpose |
|---|---|
|
|
Calls an external API to list available resources. SDMA presents the results as a selectable list when you create or edit the resource. |
|
|
Calls an external API to verify the selected resource exists. Checks the response status code against |
|
|
Controls how the connected resource appears in the Spatial Data Portal — the resource label, the ID field shown, and a deep link URL to the external system. |
Discovery configuration
The following example shows how to configure resource discovery.
"resources": { "project": { "discover": { "description": "List external resources", "method": "GET", "path": "/api/resources", "type": "rest", "responseListField": "items", "labelField": "name", "valueField": "id", "fieldMappings": [ { "source": "id", "target": "external_id" } ], "pagination": { "type": "offset", "offsetParam": "offset", "limitParam": "limit", "pageSize": 100, "maxPages": 10 } } } }
-
responseListField— JSON path to the array of results in the API response. -
labelField/valueField— Which fields from each result to use as the display label and stored value. -
fieldMappings— Maps selected resource fields to metadata attribute names on the project using the canonical[{source, target}]array form. When a user selects a resource, SDMA stores these as metadata attributes on the resource. -
pagination— Optional. Supportsoffsetpagination with configurable page size and maximum pages.
Validation configuration
The following example shows how to configure resource validation.
"validate": { "description": "Verify resource exists", "type": "rest", "method": "GET", "path": "/api/resources/${external_id}", "successCriteria": { "statusCodes": [200] } }
Display configuration
The following example shows how to configure the display of connected resources in the Spatial Data Portal.
"display": { "connectedResourceName": "External resource", "displayId": { "name": "Resource ID", "value": "${external_id}" }, "deepLinkUrl": "https://example.com/resources/${external_id}" }
-
connectedResourceName— Label for this connected resource type. -
displayId— The name and value template for the ID shown in the Spatial Data Portal. -
deepLinkUrl— URL template that links to the external resource. Supports${variable}substitution.
Setting up a connector
To create a connector in the Spatial Data Portal:
-
Sign in to the Spatial Data Portal and navigate to Library settings.
-
In the Connectors section, choose the tab for the connector direction:
-
Publish content — for publish connectors that send data to external systems.
-
Derive content — for derive connectors that enrich metadata, transform content, or expose external resources.
-
-
Choose Create publisher or Create deriver.
-
Enter a connector name (5–128 characters, letters, numbers, spaces, hyphens, and underscores).
-
Select the connector type from the dropdown. The available types depend on the direction — for example, Deadline Cloud and metadata import types appear under Derive content.
-
Paste the connector configuration JSON into the JSON editor. See the individual connector type pages for configuration details.
-
Choose Create.
For integration connectors that combine publish and derive roles, set the direction to bidirectional in the connector configuration.
After creating the connector, associate it with an asset template by adding the connector ID to the template’s permittedConnectorIds list. A connector does nothing until you explicitly approve it on a template. Only approved connectors trigger for assets created under that template. For more on how connectors, templates, and projects relate, see Connectors, templates, and projects.
Important
SDMA validates the connector configuration on creation. Validation includes:
-
Configuration structure — the connector JSON must conform to the expected structure described in Connector configuration reference.
-
IAM role assumption test — SDMA attempts to assume the configured role. If the role’s trust policy does not allow assumption, creation fails.
-
Role name prefix check — the role must start with
SpatialDataManagementContentPublisher-(publish connectors) orSpatialDataManagementContentDerivation-(derive connectors). -
Configuration size limit — the connector config must not exceed 350 KB.
Connector configuration reference
Every connector configuration is a JSON object with the following top-level structure:
{ "direction": "publish", "connectorType": "RESTApi | S3 | lambda | eventbridge | ...", "enabled": true, "connectorConfig": { "securityConfig": { ... }, "fieldMappings": [ ... ], "triggers": [ ... ] } }
The connectorConfig object contains the connector-specific settings described below.
Security configuration
Every connector requires a securityConfig that tells SDMA how to authenticate with the target service.
| Field | Required | Description |
|---|---|---|
|
|
Yes |
Authentication method. One of |
|
|
Yes (for |
ARN of the IAM role to assume. The role’s trust policy must allow SDMA to assume it. |
|
|
Yes (for |
ARN of the Secrets Manager secret containing the credential. |
|
|
Yes (for |
Where to send the key: |
|
|
No |
Custom header name for API key or token authentication. |
|
|
Yes (for |
URL to request an access token from. |
Field mappings
Field mappings transform SDMA resource metadata into the structure expected by the target system. Define them at the connector level (shared by all triggers) or at the step level (overrides connector-level mappings).
Each mapping has a source and a target:
"fieldMappings": [ { "source": "asset.assetName", "target": "properties.title" }, { "source": "project.projectId", "target": "properties.projectId" }, { "source": "literal:Feature", "target": "type" }, { "source": "asset.files[*].size", "target": "files[${file.path}].size" } ]
Supported source types:
-
Standard path — dot-notation path into SDMA metadata, for example
asset.assetNameorproject.projectId. -
Literal string — prefix with
literal:to set a static string value, for exampleliteral:Featureorliteral:data. -
Literal array —
literal:with a JSON array, for exampleliteral:["data"]orliteral:["thumbnail","overview"]. -
Literal object —
literal:with a JSON object, for exampleliteral:{"format":"GeoTIFF","compression":"deflate"}. -
File download URL — use
file.contentUrlorasset.files[].contentUrlto generate an SDMA API-routed file download URL. Usefile.presignedUrlorasset.files[to generate a direct S3 presigned URL for the file content. SDMA computes both at execution time from the file hash and asset context. -
GeoJSON bounding box — prefix with
geoJson:to convert a geometry field to a[minX, minY, maxX, maxY]bounding box, for examplegeoJson:asset.geoLocation. -
Timestamp — use
system.timestampto insert the current UTC timestamp in ISO 8601 format. -
Array iteration — use
[]to iterate over arrays, for exampleasset.files[orasset.files[*].size.
Supported target types:
-
Flat field — for example
idorassetName. -
Nested path — dot-separated path that creates nested objects, for example
properties.title. -
Array index — sets a specific position in an array, for example
geometry.coordinates[0]. -
Dynamic dictionary key — use
${variable}inside brackets to create dictionary entries keyed by a field value, for exampleassets[${file.path}].href.
Triggers
Triggers define when and how the connector runs. Each trigger specifies which resources and events activate it, and what steps to execute.
"triggers": [ { "description": "On asset creation, publish metadata to S3.", "resources": ["asset"], "events": ["create", "onDemand"], "stepType": "s3PutObject", "steps": [{ ... }] } ]
| Field | Required | Description |
|---|---|---|
|
|
Yes |
Which resource types activate this trigger. One or more of: |
|
|
Yes |
Which events activate this trigger. One or more of: |
|
|
No |
Default step type for all steps in this trigger. One of: |
|
|
Yes |
Array of step objects to execute when the trigger fires. |
|
|
No |
Optional filter to restrict which files activate the trigger. Supports |
Steps
Each step defines a single action. The step type determines which fields are relevant.
| Step type | Description |
|---|---|
|
|
Makes an HTTP request. Configure |
|
|
Invokes an AWS Lambda function. Configure |
|
|
Sends an event to Amazon EventBridge. Configure |
|
|
Writes a JSON object to Amazon S3. Configure |
|
|
Deletes an object from Amazon S3. Configure |
|
|
Submits a batch processing job to AWS Deadline Cloud. Configure |
Common step fields:
-
s3Config— for S3 steps, setobjectKey(supports${variable}interpolation) and optionallybucketNameto override the connector-level bucket. -
payload.fields— array of top-level field names to include in the output. The connector writes only these fields and excludes all others. -
fieldMappings— step-level field mappings that override the connector-level mappings. -
securityConfig— step-level security config that overrides the connector-level config. -
onError— set tofail(default) orrecord-and-continue.
Failure policy
Connectors support a failure policy that automatically disables the connector when too many failures occur within a time window. Configure this at the connector level:
"failurePolicy": { "maxFailures": 5, "windowMinutes": 10, "onExceeded": "disable" }
-
maxFailures– Number of failures within the time window before the policy action triggers. Defaults to5. -
windowMinutes– Rolling time window (in minutes) for counting failures. If the window expires without reaching the threshold, the failure count resets. Defaults to10. -
onExceeded– Action to take when failures exceed the threshold. Currently onlydisableis supported.
When failures exceed the threshold, SDMA sets the connector status to FAILURE_COUNT_EXCEEDED and disables it. Re-enable the connector manually after resolving the underlying issue.
Error handling
SDMA automatically records connector invocation results. Each invocation tracks:
-
Status – One of the following:
-
QUEUED– The invocation is queued for execution. -
IN_PROGRESS– The invocation is currently executing. -
SUCCEEDED– The invocation completed successfully. -
FAILED– The invocation failed during execution. -
NOT_APPLICABLE– The connector was attached but no trigger matched the event, so no work was performed. -
WAITING– The invocation is waiting for an upstream connector to complete (seedependsOnin trigger configuration). -
DEPENDENCY_BLOCKED– An upstream connector that this invocation depends on has failed, so this invocation was not executed.
-
-
Exception details – Error message, type, and context for failed invocations
Steps support per-step error handling by using the onError field:
-
fail(default) – Stop execution and mark the invocation as failed. -
record-and-continue– Record the error and continue to the next step. Use this in multi-step triggers when a step is non-critical. For example, a notification step should not block the rest of the workflow if the notification service is temporarily unavailable.
For multi-step triggers, the sleepTime and retryCount fields on individual steps control retry behavior. Use the successConditions block to define custom success criteria (for example, waiting for a resource to be deleted before proceeding).
In multi-step connectors, error handling interacts with step composition. If a step with onError: fail fails, SDMA marks the entire invocation as failed and does not execute subsequent steps. If a step with onError: record-and-continue fails, SDMA records the error but continues to the next step. The invocation status reflects the overall outcome — SUCCEEDED if all steps completed (even if some recorded errors), FAILED if any fail-mode step failed.
Security model
SDMA enforces multiple layers of security to isolate connector execution and limit the impact of misconfiguration.
Network isolation
Connector step execution runs in isolated AWS Lambda functions within the SDMA deployment account. These functions:
-
Execute in a private VPC with no direct inbound internet access.
-
Access external services only through configured IAM roles and security credentials.
-
Do not share execution context, memory, or temporary storage between connectors or between invocations.
Each connector invocation is an independent, stateless execution. A failure or misconfiguration in one connector does not affect other connectors or the core SDMA service.
IAM role isolation
Every connector authenticates with external services through a dedicated IAM role that you create and control in your own AWS account. SDMA enforces the following constraints:
-
Role name prefix — The role must start with
SpatialDataManagementContentPublisher-(publish connectors) orSpatialDataManagementContentDerivation-(derive connectors). SDMA rejects roles that do not match the expected prefix for the connector direction. -
Assumption test on creation — SDMA attempts to assume the role when you create the connector. If the trust policy does not permit assumption, creation fails.
-
Least privilege — The role’s permissions policy determines exactly what the connector can do. SDMA does not grant any additional permissions beyond what the role allows.
You control the blast radius of each connector by scoping the IAM role’s permissions. For example, you can restrict an S3 connector role to a single bucket and prefix, preventing the connector from accessing any other resources in your account.
Credential management
For connectors that use API keys, tokens, or basic authentication, you store credentials in AWS Secrets Manager. SDMA retrieves credentials at execution time and does not cache or persist them. The connector’s IAM role must have permission to read the specific secret.