Skip to main content

How your credentials stay protected

Why TaskJuice encrypts connection credentials at rest, never returns them to the browser, and refreshes or revokes them on demand.

When a workflow connects to GitHub, Stripe, or any other app, it needs a credential: an OAuth token, an API key, a basic-auth pair, a database connection string, or a custom secret. That credential is the most sensitive thing TaskJuice holds on your behalf. This page explains how it is stored, why the value never travels back to your browser, and what happens when a token rotates or a connection is revoked.

The short version: the database that runs your account never holds the secret itself. It holds a reference to it. The secret lives in a separate encrypted store, and only trusted server processes can read it.

The connection row holds a handle, not the secret

Every connection you create is one row in your account's database. That row carries the things you need to see and manage: the app it connects to, a human label, the connection status, and non-sensitive metadata such as a subdomain. What it does not carry is the credential value.

Instead, the row stores a reference handle: a small pointer that names where the secret lives in the encrypted store, plus a record of when it was last read. The handle is not the secret. Reading the connection row tells you that a credential exists and is healthy; it tells you nothing about what the credential is.

This split matters because it changes what someone would get from the database alone. A leaked connection row exposes a label and a pointer, not a usable token.

The handle is server-managed. It can be written only by trusted server processes, never by your browser and never by a client request. A client cannot repoint a handle at a different secret, so the only thing the handle can ever name is the secret TaskJuice created for that connection.

The credential value never reaches the browser

When you load a connection in the app or the client portal, the API returns the connection record: status, label, non-sensitive metadata, and the reference handle. It does not return the decrypted secret. There is no API response anywhere that hands a token, key, or password back to the browser.

The same boundary applies to OAuth scopes. The list of scopes a connection was granted is access-gated on the connection record itself, so even an agency's client cannot read the scopes that were authorized on their behalf. Scope visibility is reserved for the people who configure workflows, not the people who only authorize a connection.

Non-sensitive fields are treated differently on purpose. A value like a subdomain is mirrored into the connection's metadata so workflows can resolve templates against it. Sensitive fields are never mirrored: they exist only in the encrypted secret store.

Credentials are encrypted at rest and in transit. The decrypted value is read only at the moment a workflow step needs it, by the execution infrastructure that runs your steps, and it is never persisted back into your account's database in plaintext.

Where this shows up in the portal

A client who authorizes an app sees only the connection status and a label such as "Connected and working." They never see the token they granted, because that token was issued to the provider's consent screen, not typed into TaskJuice.

OAuth tokens rotate automatically

OAuth access tokens expire. TaskJuice refreshes them for you before they do, so you do not manage token rotation by hand.

Each OAuth connection tracks when its token expires and schedules a proactive refresh well ahead of that deadline, at roughly 80 percent of the token's lifetime. When the refresh runs, the new tokens are written as a fresh version of the same secret, and runtime always reads the latest version. The handle on the connection row stays the same; only the version it points to advances.

You can also trigger a refresh yourself. In the client portal, the connection detail page has a Refresh credential button, available whenever the connection is an OAuth connection with a provider configured and a stored secret. It calls the connection's refresh path and, on success, shows "Connection refreshed." If the refresh cannot complete, you see "Failed to refresh connection" with the hint that you may need to reconnect.

API keys, basic-auth credentials, DSNs, and custom secrets do not refresh on a timer. They change when you replace them, by reconnecting the app. There is no automatic rotation for non-OAuth credential kinds, and there is no client-facing form to type a new secret in by hand: a new credential always comes from the provider's consent screen or a fresh connect.

Revocation is immediate and self-service

Revoking a connection flips its status to revoked. From that moment the credential is no longer used to run workflows, and any workflow that depends on it pauses until you reconnect.

Revocation is self-service for the person who owns the credential. If you authorized a connection through the client portal, the connection detail page shows a Revoke button. Confirming it warns you that workflows depending on the credential will pause until someone reconnects, and reassures you that you can reconnect at any time from that page or from a future request email. Account and workspace admins revoke through the standard management path instead. Either way, the credential owner can pull access without having to ask the agency to do it for them.

Revocation does not stop at the connection. It cascades:

  1. Flip the connection to revoked

    The connection status becomes revoked. Revocation is idempotent, so revoking an already-revoked connection simply returns its current state rather than erroring.

  2. Revoke the linked requests

    Any client connection request that was fulfilled by this connection is flipped to revoked automatically, so the agency editor reflects the change right away.

  3. Purge the secret when you delete

    Revoking marks the connection unusable. Deleting it goes further: a cleanup step removes the underlying stored secret entirely, and the connection's grants are removed with it.

This is the published retention commitment in plain terms: connection credentials are kept until you disconnect the integration or delete your account, and revoked tokens are purged immediately.

What a revoke request can return

The self-service revoke path is intentionally narrow. Only the credential owner or a super-admin may call it, and it answers with concrete status codes so you can tell why an attempt did not succeed.

StatusMeaning
200The connection was revoked, or was already revoked (the current row is returned either way).
401 UnauthorizedThe request arrived without an authenticated user.
400 Connection ID is requiredThe request did not name a connection.
404 Connection not foundNo connection matches the given id.
403 ForbiddenThe caller is neither a super-admin nor the connection's owning identity.
500 Failed to revoke connection. Please try again.An unexpected error occurred; the connection state is unchanged.

The 403 case is the one worth understanding. The revoke path checks that you are the identity that authorized the connection. A workspace client cannot revoke another client's connection through this path, and an admin who wants to revoke a connection they do not personally own uses the standard management path instead.

Revoking pauses dependent workflows

A revoked credential is gone from every run that needs it. Workflows that depend on it pause until the connection is reconnected. If a run paused unexpectedly, check whether a credential it relied on was revoked or fell into an error state.

Connection status, and what each state means

A connection carries one of four statuses. New connections start as pending.

StatusWhat it means
activeConnected and working. The credential is in use.
pendingCreated but not yet confirmed; waiting for the first sync.
errorThe credential needs attention. This is the reconnect-needed state.
revokedAccess was pulled. Workflows using it pause until you reconnect.

There is no separate "needs reauthorization" status on a connection: error is that state. The broader "needs reauthorization" alert you may see on a paused run is a runtime concept covered under monitoring, not a connection status.

Honest limits

A few things this design does and does not do, so you know exactly where the boundaries are.

TaskJuice refreshes OAuth tokens automatically, but only OAuth tokens. The other credential kinds (API Key, Basic Auth, DSN, Custom) change only when you reconnect the app.

Revoking a connection is idempotent and immediate, but it is not a recall of data the provider already returned to a completed run. It stops future use of the credential; it does not reach into history.

Deleting a connection purges its stored secret, but revoking alone does not delete the row. A revoked connection stays visible (marked revoked) so you can see what happened and reconnect, until you or your account lifecycle removes it.

TaskJuice holds no security certifications, and nothing on this page should be read as one. It describes how the product handles your credentials, not a compliance attestation. For the named services that process data on TaskJuice's behalf and how you are notified of changes, see the published subprocessor list.

Was this helpful?