> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stackshift.cloud/llms.txt
> Use this file to discover all available pages before exploring further.

# Media Workflow authority, integrations, and recovery

> Operate workflow grants, execution principals, durable waits, restricted HTTP connections, signed inbound hooks, retries, cancellation, and post-publish warnings.

<Tip>
  **Live.** This area is documented as current, user-reliable behavior.
</Tip>

## Goal

Keep workflow automation fail-closed before publication and recover a run without repeating successful idempotent work.

## Prerequisites

* An immutable published workflow version
* Access to workflow approvals and run history

## Workflow

<Steps>
  <Step>
    Review the semantic diff, exact resolved targets, action versions, connection revisions, cost ceiling, frequency, and expiry before approval.
  </Step>

  <Step>
    Activate only after a reusable version grant exists, or allow per-run nodes to pause for their own approval.
  </Step>

  <Step>
    Inspect waiting runs by wait reason: approval, durable delay, event, or child operation.
  </Step>

  <Step>
    Retry a failed run from its failure closure; cancel when a cancellable child operation must stop.
  </Step>

  <Step>
    Rotate an HTTP credential or inbound hook through the dedicated endpoint, then republish/reapprove any version whose bound connection revision changed.
  </Step>
</Steps>

## Execution authority and approvals

* Every run revalidates that its execution principal exists and still owns or can access every referenced resource. Permission loss disables new trigger dispatch and fails an unexecuted unauthorized node.
* `none` applies to reads and bounded reversible actions. `version` binds reusable authority to semantic digest, action versions, resource selectors, connection revisions, frequency, cost ceilings, and expiry. Default expiry is 90 days; an approver may choose 1 minute–365 days.
* `per_run` is mandatory when a costly or production target/value is dynamic. A version grant cannot silently satisfy a per-run action.
* Asset publish, rollback, restore/promotion, public-access changes, production stop/restart, external HTTP, and billable generation receive production, external, or cost policy treatment.

## Restricted external HTTP

* A connection stores one exact public HTTPS hostname on port 443, 1–20 allowed path prefixes, safe default headers, encrypted credential reference, and revision. Scheme and host cannot be interpolated.
* Methods are GET, POST, PUT, and PATCH. Paths must remain under an allowed prefix; userinfo, fragments, traversal, IP literals, loopback, private/link-local/metadata ranges, DNS rebinding, and redirects outside the allowlist are blocked.
* Request body limit is 256 KiB; response limit is 1 MiB; timeout is 1–30 seconds; redirects are capped at three. Retry is limited to timeouts, 408, 429, and 5xx with a stable idempotency key and at most five attempts.
* Persisted output contains sanitized status, selected response headers, duration, and truncated/redacted data. Authorization, tokens, secrets, passwords, cookies, hop-by-hop headers, and connection credentials are not exposed.

## Signed inbound webhook

* Rotate the inbound hook only after the workflow is active. The token and derived signing secret are disclosed in that response; store them in a secret manager.
* Payload must be valid JSON and no larger than 1 MiB. Timestamp skew is limited to five minutes. Delivery ID is required and capped at 160 characters.
* Delivery ID plus payload digest provides replay/idempotency protection. Reusing an ID with different bytes is rejected; an exact replay returns the already-created run.

```bash theme={null}
TIMESTAMP=$(date +%s)
DELIVERY_ID="media-$(uuidgen)"
# Signature input is: TIMESTAMP + "." + DELIVERY_ID + "." + exact request bytes.
curl -X POST "https://api.stackshift.cloud/api/v1/assets/workflow-hooks/$HOOK_TOKEN" \
  -H "Content-Type: application/json" \
  -H "X-Stackshift-Timestamp: $TIMESTAMP" \
  -H "X-Stackshift-Delivery: $DELIVERY_ID" \
  -H "X-Stackshift-Signature: sha256=$HEX_HMAC" \
  --data-binary '{"asset_id":"..."}'
```

## Durability, retry, and recovery

* A workflow is one durable parent job with persistent node execution rows. Inputs/outputs, attempts, leases, waits, timing, branch ports, structured errors, Stackie activity, and cost are checkpointed after sanitization.
* Delays, approvals, platform events, and child operations persist a wait directive and resume through the durable job/event path instead of holding a request open.
* Retry computes the failed-node descendant closure, resets only that closure, and preserves successful upstream idempotent checkpoints. Cancellation propagates to supported child jobs.
* Asset events enter a transactional outbox from the asset event insert; the scheduler claims with leases, dispatches matching active versions idempotently, backs off failures, and dead-letters after 20 attempts.
* Alert on active/ready/waiting node counts, stuck joins, event lag, child-operation waits, approval expiry, Stackie budget exhaustion, SSRF blocks, MCP calls, transform queues/cache, and AI spend reconciliation.

## Expected result

<Check>
  Failures before publication leave the asset private and side-effect free; exhausted post-publication notification/integration work yields `completed_with_warning` without silently unpublishing.
</Check>

## Related guides

<CardGroup cols={2}>
  <Card title="Media Workflows visual builder and API" href="/assets/media-workflows">
    Author editable templates or blank typed DAGs that coordinate asset gates, native StackShift services, bounded Stackie reasoning, and approved external integrations.
  </Card>

  <Card title="Stackie asset tools and MCP" href="/assets/stackie-asset-tools-and-mcp">
    Use the same governed asset actions from Stackie, workflow Stackie nodes, and stateless Streamable HTTP MCP clients.
  </Card>

  <Card title="Durable Jobs workflows" href="/durable-jobs/workflows">
    Use steps and events to build multi-step jobs that can retry, pause, and resume.
  </Card>
</CardGroup>
