Skip to main content

Collect client credentials safely

Use first-party intake so clients authorize apps through the provider's own consent screen, and no secret ever passes through email or chat.

When a workflow needs to act on a client's account, the client has to grant access. The unsafe version of this is asking them to paste an API key into an email or a chat message, where it sits in plain text in two inboxes forever. TaskJuice replaces that with first-party intake: you queue a request, the client authorizes through the provider's own consent screen, and the resulting credential is stored as a server-managed secret that never returns to anyone's browser.

This page shows you how to collect a credential this way and what guarantees the flow gives you.

When to use this

Use first-party intake whenever a node in a workflow runs against an account your client owns, such as their Slack workspace, their HubSpot portal, or their Google account. You set the node's connection source to Client provides the connection, and the client connects the app themselves.

This flow is OAuth-only. The client authorizes through the provider's consent screen; they never type an API key, password, or token into TaskJuice or hand one to you. If an app you need only authenticates with an API key, that app is not eligible for client intake, and you connect it yourself from the integrations area instead. See Connect an account.

What the client never has to do

The whole point of first-party intake is what it removes from the handoff. No part of this flow asks the client to share a secret with you or with TaskJuice:

  • The client never emails, messages, or dictates an API key, password, or token to you.
  • The credential is entered only at the provider's own consent screen, the same screen they would see signing in directly.
  • The email TaskJuice sends carries a single sign-in link plus the app names, the permission labels, and your note. It contains no secret, no password, and no token. The email states this in plain language: it tells the client your agency "never sees your password" and that connecting "uses the provider's own consent screen."

Collect a credential

  1. Set the node to use a client connection

    Open the node that needs the credential in the workflow editor. In its connection section, choose Client provides the connection. The slot explains that the client will connect the app from their portal or through a sign-in link, then shows an Add to client request queue button.

  2. Queue the request

    Click Add to client request queue. The modal is titled Add {app} request to queue and reads: "Queue a connection request for this app. No email is sent until you send the queued requests to the client."

    Enter a recipient under Recipient email. The combobox lists existing workspace members, and any well-formed address you type appears under an Other group. The channel hint below the field tells you which path the recipient gets:

    • A workspace member connects inside the portal and has 4 hours from when you send to connect.
    • A net-new email (no portal account) gets a sign-in link and has 7 days from when you send to connect.

    Add an optional Note to client (up to 256 characters) explaining why you need the connection. The requested OAuth scopes show as read-only badges; they come from the app's action definition and are not editable here. Click Add to queue.

    Queuing does not send anything. A queued request is invisible to the client and never expires on its own. It waits until you send it or until you cancel it.

  3. Send the queued requests

    Open the Client connection requests panel from the editor sidebar. It groups every queued and dispatched request for this workflow by recipient. Click Send to client to dispatch them. TaskJuice mints a fresh link, sets the expiry clock, and sends exactly one email per recipient that covers every app in their bundle, never one email per app. You will see a "Sent requests to client" confirmation reporting how many recipients and requests were covered.

    You can skip this step in one case: publishing the workflow auto-sends any still-queued requests for that workflow, so the client gets the email at publish time without you clicking Send to client first. See Publishing a workflow version.

  4. The client authorizes through the provider

    The client opens their link. A workspace member lands in their portal inbox under Outstanding connection requests; a net-new recipient lands on an agency-branded page titled "{your agency} needs you to connect {n} app(s)" with no TaskJuice branding. Either way, each app has a Connect {app} button that opens the provider's own consent screen.

    The client approves the requested permissions at the provider. The credential the provider issues is sent back to TaskJuice and stored as a server-managed secret. The request flips to Connected and the node is unblocked.

Verify it worked

Open the Client connection requests panel in the editor. A connected request shows the Connected badge (or "Connected as {email}"). The node's connection slot in the editor shows the same connected state instead of the queue button.

On the client side, the connection now appears in their portal under Connections with an active status, meaning "Connected and working." From there the client owns the connection: they can refresh or revoke it themselves without coming back to you. For how that side works, see Manage client connections.

How the credential stays protected

Every link TaskJuice sends is signed, bound to one tenant, workspace, and recipient, and expires on its own (4 hours for portal recipients, 7 days for sign-in-link recipients). Resending a request mints a new link and invalidates the old one, so the client always has at most one working link at a time. Each resend is capped at 3 per request with a 5-minute minimum between sends.

If a link is expired, already used, or tampered with, the client sees a single deliberately vague screen titled This link can't be opened that reads: "It may have expired, already been used, or is otherwise invalid. Ask the requester to send you a fresh link." The screen looks identical for every failure reason on purpose, so a stranger cannot probe which links exist.

The credential itself never reaches a browser. The connection record stores only a reference to the secret, not the secret value, and that reference is writable only by trusted server processes. Even the granted OAuth scopes are access-gated. For the full storage model, see How credentials are stored.

Troubleshooting

The client says the link no longer works

Links expire 4 hours after you send (portal recipients) or 7 days after you send (sign-in-link recipients), and any resend invalidates the previous link. If the client clicks an old or expired link they see "This link can't be opened." Open the Client connection requests panel and use Resend email on the pending row to mint a fresh link. Resending is limited to 3 times per request with at least 5 minutes between sends; the button shows the remaining count and cooldown.

If Resend email is unavailable, the request has not been sent yet. You can only resend a request that has already been dispatched and is still waiting on the client. Send it first with Send to client.

If the app you need is not eligible for client intake, it does not authenticate with OAuth. The intake flow rejects any provider that is not configured for OAuth2, with the message "OAuth provider on this request is not configured for OAuth2." Connect that app yourself from the integrations area instead of requesting it from the client.

To stop waiting on a request, open the Client connection requests panel and use Cancel on the row. Only you can cancel a request; the client cannot. Cancelling clears the linked slot, so you will need to re-add that request before publishing.

Was this helpful?