File connector workers¶
The independently operated workers/files package provides FTP, explicit FTPS, SFTP, Microsoft Graph drives (SharePoint and OneDrive), and Google Drive actions. Binary data travels through the file API as bounded chunks; workflow state contains a weave/file reference with its filename, content type, size and SHA-256 digest.
Operations and catalog¶
All connectors are version 1.0.0. Connector names are weave-ftp, weave-ftps, weave-sftp, weave-microsoft-drive, and weave-google-drive. An action is named <connector>-<operation>@1.0.0; its worker capability is <connector>.<operation>@1.0.0.
| Operation | Input | Result |
|---|---|---|
list |
Optional folder path or cloud itemId, limit (1–100), optional cursor |
{items, nextCursor} |
read |
File path or cloud itemId |
File metadata |
download |
File path or cloud itemId |
Verified weave/file reference |
write |
file reference and destination; cloud also requires name |
Created file metadata |
move |
path or cloud itemId, destination; cloud also requires name |
Moved file metadata |
delete |
File path or cloud itemId |
{deleted: true} |
Metadata has id, name, isFolder, and available sizeBytes, contentType, modifiedAt, version. read reads metadata; it never returns binary data in JSON. FTP/SFTP destinations are full relative file paths. Cloud destinations are parent folder IDs. SFTP writes refuse existing destinations; FTP/FTPS destination behavior requires the explicit policy described below. Graph writes request conflict failure; Google Drive creates a new file and permits duplicate names according to Drive semantics. Deletion is file-only: recursive folder deletion is unavailable.
uv sync --project workers/files --locked
uv run --project workers/files weave-files-worker --catalog > /tmp/files-catalog.json
uv run --project workers/files weave-files-worker --release-manifest > /tmp/files-release-capabilities.json
The catalog contains five Connector definitions, thirty Action definitions, task capabilities and adapter identities. Follow Complete your first transfer to admit the image, publish these definitions, and bind a run. Each action has a 300-second bound and one attempt. Writes, moves and deletions have non_idempotent side effects; an uncertain result must be investigated before an operator retries.
Connections and authority¶
Connections use the existing secret-handle system. The API validates public configuration; only a worker holding the current task lease obtains its pinned connection metadata and short-lived credential lease. Each config explicitly lists permitted operations.
| Connector | Required public config | Secret slot | Allowed destination |
|---|---|---|---|
| FTP / FTPS | host, port, username, rootPath: /, serverRootIsolated: true, operations; optional destinationPolicy |
password |
ftp://host:port / ftps://host:port |
| SFTP | host, port, username, rootPath: /, serverRootIsolated: true, OpenSSH hostKey, operations |
password |
sftp://host:port |
| Microsoft drive | driveId, rootFolderId, operations |
accessToken |
https://graph.microsoft.com |
| Google Drive | rootFolderId, operations |
accessToken |
https://www.googleapis.com |
Example SFTP connection configuration:
host: files.example.com
port: 22
username: weave
# First isolate this account to the approved folder on the server.
# That folder appears as / when this account signs in.
rootPath: /
serverRootIsolated: true
hostKey: ssh-ed25519 REPLACE_WITH_THE_VERIFIED_SERVER_PUBLIC_KEY
operations: [list, read, download]
The host key is public identity evidence; obtain it through the operator's trusted channel. Unknown or mismatched SSH host keys fail closed. Passwords and OAuth access tokens belong in credential providers, never in these files. Cloud token scope and renewal remain the credential provider's responsibility; this package does not implement an interactive OAuth login or store refresh tokens.
FTP, FTPS, and SFTP require an account whose root is isolated by the server. Configure an operating-system chroot or an equivalent boundary that also prevents symbolic links from reaching outside the approved folder. A virtual folder prefix alone is insufficient. Set rootPath: / and serverRootIsolated: true only after the server administrator has established this boundary. The worker cannot verify that administrator assertion over the protocol. A narrower client-side path is not a security boundary: another writer could change directories between checking a path and opening it.
SFTP additionally checks path components and rejects observed symbolic links. All three connectors reject parent traversal, absolute operation paths, backslashes, and control characters. Cleartext FTP is disabled unless the worker operator explicitly enables it. FTPS upgrades the control connection before login and encrypts its data connections; certificate and hostname verification remain enabled.
Choose safe destination behavior¶
Use SFTP when a transfer must never replace a concurrently created destination. SFTP writes use exclusive creation and moves use the protocol's no-replace rename. FTP and FTPS cannot make the existence check and subsequent write or rename one atomic operation. Therefore their default destinationPolicy: requireAtomicNoReplace permits listing, reading, downloading, and deleting, but rejects write and move.
If a legacy FTP server is required and the application accepts this limitation, the connection must explicitly set destinationPolicy: allowNonAtomic and the worker policy must separately set allowNonAtomicFtpDestinations: true. Both are required. The connector still refuses destinations it observes already existing, but a concurrent writer can create a destination after that check and have its data overwritten. Keep the default when that behavior is unacceptable.
Cloud access verifies item ancestry against rootFolderId, bounded to 32 levels. SharePoint uses an explicit Graph drive ID for the selected document library; OneDrive uses its drive ID. Remote-item links and Google shortcuts are excluded. Native Google Workspace documents need an export-format operation, which this package does not currently expose; stored binary files are supported.
Worker policy and deployment¶
The worker policy adds an independent destination allowlist to each connection's scope:
{
"origins": [
"sftp://files.example.com:22",
"https://graph.microsoft.com",
"https://www.googleapis.com"
],
"downloadOrigins": ["https://tenant.sharepoint.com"],
"privateNetworks": [],
"allowCleartextFtp": false,
"allowNonAtomicFtpDestinations": false
}
Use exact origins, without wildcard hosts or paths. For Graph, configure the actual HTTPS origin used by the tenant's signed download URLs. Graph returns a preauthenticated redirect; the worker follows one allowed redirect with a separate request that carries no bearer credential. Arbitrary redirects and unexpected Google media redirects fail closed. HTTP egress resolves and pins approved addresses. FTP uses EPSV data connections to the pinned server; private servers require an explicit privateNetworks CIDR. Link-local metadata addresses remain prohibited.
| Environment variable | Meaning |
|---|---|
WEAVE_API_URL |
Platform API origin; HTTPS outside localhost |
WEAVE_ENVIRONMENT_URL |
Scoped /api/v1/tenants/.../projects/.../environments/... path |
WEAVE_WORKER_RELEASE_ID |
Admitted immutable worker release UUID |
WEAVE_WORKER_TOKEN_FILE |
Mounted rotating worker-token file |
WEAVE_FILES_POLICY_FILE |
Mounted policy JSON path |
Build the container from the repository root. Use the checked-in dependency lock so the build uses the same package versions as the release:
# The Dockerfile installs the locked worker environment.
docker build -f workers/files/Dockerfile -t weave-files-worker:local .
The image runs as UID 65532. Mount credentials and policy read-only, allow a bounded writable temporary directory, and restrict network egress at deployment as well as in policy. The worker handles one task at a time and drains on SIGTERM. Transfers stop on cancellation or loss of task authority; every Weave upload/download request rechecks the task proof.
Workflow example¶
apiVersion: weave/v1alpha1
kind: Workflow
metadata: {name: receive-invoice, version: 1.0.0}
spec:
inputSchema: {type: object}
outputSchema: {}
connections:
incoming: {connector: weave-sftp@1.0.0, required: true}
steps:
- id: invoice
kind: action
uses: weave-sftp-download@1.0.0
connection: incoming
with:
literal: {path: invoices/current.pdf}
output: {ref: /steps/invoice/output}
Bind incoming to an authorized connection revision and the action to the admitted worker release during activation. The resulting reference can feed another action or a human-task attachment without embedding file bytes in the workflow.
Complete your first transfer¶
First connect the CLI and select a workspace. If you operate a new installation, complete the manual platform setup first. Use an administrator for identity and grants, an authorized author/deployer for publication and activation, and a separate worker identity for execution. The worker deployment walkthrough explains identity linking and the real IDs returned by admission; its example Action and token acquisition are specific to that tutorial, so use this package's exports and rotating token file here.
Follow these steps in order, retaining each successful response before continuing:
-
Install and build. Run the locked install, catalog export, release export, and Docker build above. Record the actual immutable image digest of the image you will deploy; a mutable tag such as
:localis not a release identity. Establish the SFTP account's server-side root isolation, verify its host key, and prepare the worker policy before starting a transfer. -
Admit the release. Create
files-release-request.jsonby addingimage_digestto the exported/tmp/files-release-capabilities.json, retaining bothcapabilitiesandcredential_capabilities. Runweave workers releases create --request files-release-request.json --output jsonand save its returned releaseid. The release contract describes admission. These Actions execute in a remote worker; this package does not require nativeconnector_bindings. -
Publish the contracts. The catalog export is a compilation lock, not one publication request. For each selected
definitions[].document, wrap its JSON text as{"format":"json","source":"…"}using the publication-request walkthrough. Publish theweave-sftpConnector first withweave definitions publish --collection connectors --request sftp-connector-request.json --idempotency-key files-sftp-connector-1 --output json; save its versionid. Publish theweave-sftp-downloadAction the same way with--collection actionsand its own request/key. Keep their exported definitions unchanged. Publish additional Connectors and Actions when you need them. -
Create the scoped connection. Use
weave connections create --request sftp-connection-request.json --output json. The request needsname, the publishedconnector_version_id, the SFTPconfigshown above,secretRef: {"password":"YOUR_SECRET_HANDLE"}, andallowed_destinations: ["sftp://files.example.com:22"]with your actual approved origin. Save the returned connection revisionid. Follow Give integrations their secrets to provision and grant the handle; never put the password in the request. Restrict this example'soperationstodownloadif listing and metadata reads are unnecessary. -
Grant execution and credential access. Follow worker identity and grants, using
weave remote access grant --request worker-grant.jsonfor the linked worker principal. The stock process registers all thirty exported task references, so its environment-scopedworkergrant must cover the admitted release ID and all thirty references. Provider access remains restricted by connection operations, worker policy, secret-handle grants, and the exact credential grant. For this example, runweave workers grant --request sftp-credential-grant.jsonwithrelease_id,connection_revision_id, andcapability: "weave-sftp.download@1.0.0". Grant only the connection/capability combinations you intend to execute. -
Publish and activate the workflow. Save the YAML above as
receive-invoice.yaml. Use CLI publication and activation, retaining the workflow versionidanddigest. Add these bindings to the activation request alongsideversion_id,artifact_digest, and your environmentscope:{ "connection_revision_ids": {"incoming": "CONNECTION_REVISION_UUID"}, "worker_release_ids": {"weave-sftp.download": "WORKER_RELEASE_UUID"} }Replace both placeholders with the saved response IDs. The worker map key is the task type without
@1.0.0; do not substitute the Action name or use the nativeconnector_release_idsmap. Runweave definitions activations create --request files-activation-request.json --idempotency-key receive-invoice-activate-1 --output jsonand save the activationid. -
Start the worker, run, and download. Set the five worker environment variables listed above, mount the rotating token and policy files, then start
weave-files-workerusing the locked command above or the admitted image. Follow Start and inspect a run with the saved activation ID andinput: {}. Read the same run untilstate.statusissucceeded; itsstate.outputis the file reference. With a separately authorizedfile_readeridentity, runweave files download FILE_ID --to ./invoice-copy.pdf, replacingFILE_IDwithstate.output.id. The file CLI walkthrough explains checksum verification and the refusal to overwrite an existing local file.
Publishing and activating do not start worker capacity. If the run waits, check the registered worker, release pin, and grants before starting another run. Keep publication, activation, and run idempotency keys when retrying the same request; inspect uncertain external effects before retrying an operation.
Bounds and acceptance¶
Each file is limited to 25 MiB, with 256 KiB Weave chunks. A download is bounded and spooled before upload; uploads to providers use a verified Weave download. Size and digest mismatches fail before publishing a ready reference or beginning the provider write. Cloud JSON responses are limited to 1 MiB and 128 requests per task. Local protocol listings enumerate at most 1,000 entries and return at most 100 per page; pagination is a view of the live directory, not a snapshot transaction.
Inbound files can be retrieved with list/download actions invoked by an existing scheduled workflow. Dedicated provider change-feed triggers and atomically persisted polling cursors are not implemented in this package. Do not use a list cursor as a durable change-feed checkpoint.
Tests exercise real local FTP, SFTP, and FTPS servers, including certificate rejection, and mocked Graph/Google request contracts, scope restrictions and redirect credential isolation. They do not assert live Microsoft or Google access.
Provider references: Graph download redirects, Graph upload, Google uploads, Google downloads, aioftp TLS, AsyncSSH host-key verification.