Syndroodocs

Credentials

A credential is read once, validated against the provider's own schema, and then stored by Core. Publishing never re-reads the environment variable or the file you imported from.

Two explicit sources

  • --from-env reads exactly SYNDROO_CREDENTIALS: one JSON object, at most 64 KiB.
  • --credential-file reads one private JSON file with the same object shape.

Passing both, or passing neither when the provider needs credentials, is refused. An interactive run at a terminal offers the same two sources plus field-by-field entry, where a field the provider marks as secret is read with echo disabled. A non-interactive run never guesses and never blocks.

Field names by provider

ProviderCredential objectSecret fields
Blueskyidentifier, password (both required)password
Threadsclient_id, client_secret (both required)client_secret
LinkedInclient_id, client_secret (both required)client_secret
Mastodon{}: the accepted object is emptyNone: browser authorization
DEV.toapiKey (required)apiKey

Unknown keys in the credential object are refused, because every provider's credential schema sets additionalProperties to false.

# Bluesky
export SYNDROO_CREDENTIALS='{"identifier":"you.bsky.social","password":"APP_PASSWORD_PLACEHOLDER"}'

# DEV.to
export SYNDROO_CREDENTIALS='{"apiKey":"DEV_TO_API_KEY_PLACEHOLDER"}'

App clients are connect options, not credentials

LinkedIn, Threads and Mastodon accept their app client through the connect options of the request document, which is how a machine caller skips an interactive prompt:

ProviderRequired connect optionsOptional connect options
BlueskyNoneNone
DEV.toNoneNone
LinkedInredirectUriclientId, clientSecret, scopes
ThreadsredirectUriclientId, clientSecret, apiHost, authorizationHost, scopes
Mastodoninstance, redirectUri, scopesclientId, clientSecret

After a credential is stored

Core keeps the credential in the local credential store and records a reference on the connection; a plugin receives only what its own operation needs. Publishing does not depend on the environment variable or the import file still existing, so the file can be deleted once the connection works.

A stored credential is released when the connection is disconnected. Disconnecting removes the local record only: Syndroo never revokes a platform credential, so revoke it at the platform as well. Each platform guide says what is documented for its revocation.

Browser authorization

LinkedIn, Threads and Mastodon connect with an authorization action that a browser completes. The local CLI finishes that OAuth callback itself for all three. With --redirect-uri it binds exactly that loopback host, port and path in-process and consumes one redirect; the default is a pre-registerable loopback URI, and the bind needs a controlling terminal, so without one the run reports the pending action and exits 0. With --callback-url - it reads the redirected URL from standard input instead. A callback URL that carries code or state is refused on the command line as CALLBACK_URL_INVALID, because a secret must not reach the argument vector. This local callback path is verified by fixture tests against local HTTP servers only; no live LinkedIn, Threads or Mastodon account was connected.