Personal channels
An HTTP channel starts with shared conversations and a separate binding credential. Enable personal access when your agent needs a person’s own connected accounts or memory.
Private conversations require verified identity on every request. A project API key alone cannot read them or act for their owner.
Personal access supports signed-in project members and people authenticated by your application. Your customers do not need Sikaru accounts. Your application owns their sign-in, conversation interface, connection callback, and approval UI.
Your backend signs in its own user, signs a short-lived assertion for that user, and sends it with every message and poll. Sikaru returns a receipt. Polling the receipt returns the output, or a connection prompt or approval for the user to handle.
Register your application
In Settings → Channels → Trusted Customer Apps, register:
- An issuer and audience that your backend will put in assertions.
- A public RSA JWK with at least a 2048-bit key. Keep the private signing key on your backend.
- A connection callback URL for account authorization, and a private channel URL where your users can sign in and continue a Slack conversation. Both use HTTPS.
The returned application ID is the assertion’s kid. An operator can also register an app using POST /v1/projects/{project_id}/channels/identity-apps with a project credential.
Select the trusted app when you enable personal access on the binding. For API setup, use PUT /v1/projects/{project_id}/channels/bindings/{binding_id}/personal-access:
Personal access belongs to personal agents. Every conversation of a personal agent is personal, so its channels need personal access before they go live.
Customer private identity comes from the signed tenant_id and sub claims. It never comes from message text, actor labels, email addresses, or a browser-supplied user ID.
Prove the current user
Your backend verifies its own user’s session, then signs an RS256 JWT with this header and claims (replace the timestamps with the current time):
- Issuer and audience must exactly match the registration.
iatandexpare integer Unix seconds. Assertions last at most 600 seconds.- Only issue assertions for the verified user and tenant. Refresh them through your backend as needed.
Expiry limits reuse of a copied assertion. It does not expire connected accounts, conversation history, memory, or already accepted work. Revoking an app, subject, or link still removes current access.
A customer assertion grants no project administration privileges.
Send a private HTTP message
Keep the binding credential on your backend. Set privacy explicitly:
- Use stable message IDs when you retry an uncertain submission.
- Omitting
privacykeeps shared behavior. - Use a new conversation ID when moving from shared to private. Existing conversations do not change audience or merge old memory.
The generated clients keep channel credentials separate from the project API key:
Python
TypeScript
CLI
The personal_channels methods take an optional per-call authorization with the literal Bearer prefix. HTTP bindings require it; Slack bindings omit it. The client’s project api_key and constructor channel_credential do not supply this per-call header.
In TypeScript the corresponding group is personalChannels; the CLI group is personal-channels. Header flags appear in each command’s --help.
Omit authorization / --authorization when accessing a linked Slack binding.
Continue the same turn
Poll GET /v1/personal-channel-bindings/{binding_id}/messages/{receipt_id} with the same owner’s fresh proof. For HTTP, include the binding credential too. The response contains status, output, connection_prompts, and pending actions.
When status is connection-needed, use the prompt’s connection ID:
Start authorization
POST .../connections/{connection_id}/authorize returns url, state, and expires_at. Send the user to url.
When approval is pending, show the action’s product-visible arguments and let its owner choose. Call POST .../tool-calls/{tool_call_id}/approval with:
denied is also supported.
Account completion and approvals wake the same turn. Do not submit the original message again to continue it. Generated mutation methods do not retry automatically. If delivery is uncertain, reuse the operation’s existing identifiers and inspect the current receipt before deciding what to do next.
List the owner’s files using GET .../files, then download bytes from GET .../files/{file_id}/content.
Every receipt, action, and file request rechecks owner access. Project-reader authority and another person’s proof do not expose private content. A paused or revoked binding stops private access too.
Link a private Slack DM
A shared Slack room never gains a person’s accounts or private memory. Linking a DM requires proof from both the authenticated app user and the Slack recipient; email matching is not used.
Request a link
With the authenticated user’s proof, call POST /v1/personal-channel-bindings/{binding_id}/slack-links with body {"installation_id":"installation_id"}. An HTTP bootstrap binding also needs its binding credential.
Verify in Slack
Have the user send sikaru verify <challenge> to the installed Slack bot in a DM, replacing <challenge> with the returned challenge.
Slack status messages link to your registered private channel URL with binding_id and receipt_id. Authenticate the user there before loading content; the URL itself contains no authorization. Customer DM bindings require that URL to be configured. Project members can link and unlink their own Slack identity in the dashboard.
To unlink, call DELETE /v1/personal-channel-bindings/{binding_id}/slack-links/{installation_id} with the current owner’s proof. Relinking does not grant old conversations to a new owner. Operators can revoke an entire trusted app or a specific subject/tenant through the app management endpoints.
Control memory separately
Under the agent’s Memory capability, Shared Memory and Personal Memory can be controlled independently. The main Memory switch disables both.
- Private turns read and write only user memory.
- Disabling Personal Memory turns channel memory off rather than falling back to shared memory.
- User memory follows the verified person within the same tenant and agent across explicitly linked private HTTP and Slack channels.
Turning access or memory off takes effect on later access and capture checks. Revocation is an access control, not a way to undo a tool action already completed.
