Highlights
OAuth apps, personal access tokens and consent require a sign-in session
OAuth app management and the consent endpoints accepted OAuth access tokens and personal access tokens. A token with any scope could create an app with broader scopes, read or regenerate client secrets, or approve a consent request for itself. Every/oauth-clients/* and /personal-access-tokens/* route, the consent POST /oauth2/authorize, and the device-flow /device/verify and /device/consent routes now require the user’s interactive session JWT, and answer 403 to OAuth access tokens and PATs. PAT scopes are capped at the instance’s MCP_SCOPES (#3626 — @rish664).
PKCE enforced where the code is issued and redeemed
PKCE was checked only onGET /oauth2/authorize, which returns consent data, not the code. A caller that skipped the GET could get a public-client code without a challenge and redeem it with no verifier and no client secret, and the plain method let a caller send its own challenge back as the verifier. A public client now must send a code_challenge to the consent POST, only S256 is accepted, and discovery advertises only S256 (#3630 — @rish231294).
Record convert API: no more writes outside the temp folder
POST /api/v1/record/buffer/convert built its temp file path from the unsanitized upload filename, so an absolute path or ../ in the name let any signed-in user write a file anywhere the connectors service could write. The filename is no longer trusted for the path (#3628 — @rish231294).
Breaking changes & upgrade notes
- OAuth app, personal access token, consent and device-flow routes reject OAuth access tokens and PATs with
403. This covers/oauth-clients/*,/personal-access-tokens/*,POST /oauth2/authorize,/device/verifyand/device/consent. Scripts that manage OAuth apps, mint PATs or approve a device login with a token must use a user’s sign-in session instead (#3626). - PKCE
plainis rejected with400. Public clients must send anS256code_challengeon both the authorizeGETand the consentPOST; without it the consent redirects witherror=invalid_requestand no code. Confidential clients may still omit PKCE (#3630). - The service-account email domain is reserved. A person can no longer be given an address in
service.pipeshub.internal, through invites, user creation or an email change (#3612). - SDK users: the 1.7.0 SDKs contain breaking changes. See the next section.
SDKs — 1.7.0 (TypeScript, Python, Go)
The TypeScript, Python and Go SDKs move from 1.6.0 to 1.7.0, released on October 12, 2026, and are compatible with PipesHub 0.9.1:@pipeshub-ai/sdk (v1.7.0 release), pipeshub-sdk (v1.7.0 release) and pipeshub-sdk-go (v1.7.0 release), all by @rish664.
1.7.0 is a minor version, but it contains breaking changes. Read the list for your language before you upgrade.
TypeScript
Renaming a conversation no longer returns messages
updateConversationTitle returns only the updated conversation fields. Read the messages with a second call.
Deleting an agent conversation: conversation can be empty
conversation is now a stored conversation, an empty object, or null. Check it before you read a field.
Some type names changed
Use the new name. The data inside is the same.
The
UpdateConversationTitle* message types are removed, because renaming a conversation no longer returns messages.
Two errors have a new error class
A500 from knowledgeBase.uploadRecords is now thrown as ErrorResponse. A 410 from userAccount.authenticate is no longer an ErrorResponse. Both classes extend PipeshubError, so catch the parent class and check the status code.
Behavior notes (not breaking)
- A user token on 22 endpoints. OAuth apps, personal access tokens, user info, org auth config and reset password now send only the user token. If you set up only an app token, add a user token:
- Stream event
datastays a string. Code that callsJSON.parse(event.data)keeps working.
Python
Renaming a conversation no longer returns messages
update_conversation_title returns only the updated conversation fields. Read the messages with a second call.
Deleting an agent conversation: conversation can be empty
conversation is now a stored conversation, an empty object, or None. Your code runs as before, but type checkers need a check before you read a field.
Some type names changed
Use the new name. The data inside is the same. All names are inpipeshub_sdk.models.
The
UpdateConversationTitle* message types are removed, because renaming a conversation no longer returns messages.
Two errors have a new error class
A500 from knowledge_base.upload_records is now raised as ErrorResponse. A 410 from user_account.authenticate is now PipeshubDefaultError, not ErrorResponse. Both classes extend PipeshubError, so catch the parent class and check the status code.
A citation can have two shapes
A message citation is now aCitationReference or a PopulatedCitationReference. Your code runs as before, but type checkers need a check before you read a field.
Behavior notes (not breaking)
- A user token on 22 endpoints. OAuth apps, personal access tokens, user info, org auth config and reset password now send only the user token. If you set up only an app token, add a user token:
- Conversation streams work.
dataonConversationStreamSSEEventandConversationMessageStreamSSEEventis typedAny, as on the other stream models. The SDK decodes each event’s JSON before validation, so the oldstrtype rejected those events.
Go
Go 1.26.8 or newer is required
go.mod now declares go 1.26.8 (it was go 1.22). Upgrade Go, or keep the default GOTOOLCHAIN=auto so that Go downloads the toolchain.
Renaming a conversation no longer returns messages
UpdateConversationTitle returns only the updated conversation fields. Read the messages with a second call.
Deleting an agent conversation: Conversation can be empty
Conversation is now a *components.ConversationUnion, which can be nil, a stored conversation, or an empty object.
Some type names changed
Use the new name. The data inside is the same. Enum constants take the new prefix too, for exampleoperations.IsArchivedTrue becomes operations.ListAgentConversationsIsArchivedTrue.
The
operations.UpdateConversationTitle* message types are removed, because renaming a conversation no longer returns messages.
Two errors have a new error type
A500 from KnowledgeBase.UploadRecords is now returned as *apierrors.ErrorResponse. A 410 from UserAccount.Authenticate is now the default *apierrors.APIError, not *apierrors.ErrorResponse. Check for both types.
Success is always true
On the delete-record, reindex-record, reindex-record-group and knowledge-hub-nodes responses, Success is no longer a public field. A 200 already means success, so you can drop the check, or use the getter.
A citation can have two shapes
A message citation is now acomponents.CitationUnion: a CitationReference or a PopulatedCitationReference. Read the citation through its wrapper.
Behavior notes (not breaking)
- A user token on 22 endpoints. OAuth apps, personal access tokens, user info, org auth config and reset password now send only the user token. If you set up only an app token, add a user token:
- Stream event
datastays a string. Code that reads*ev.Datakeeps working.
Agents & AI
- Graph enrichment respects permissions. The parents, children and attachments that enrichment adds to search results (Jira, Confluence, Linear) are now permission-checked in one batch, and their number is capped, so names, URLs and summaries of records a user cannot open no longer reach the prompt. A new
filter_accessible_record_idsprovider method backs it on Neo4j and ArangoDB (#3590 — @darshangodase). - Agent tools — behaviour tests for the GitHub, Jira and ClickUp tools, and fixes for the bugs they found (#3582); the agent answers from the workspace’s data when the Acme Corp demo is its only knowledge (#3609) — @shekharkadyan.
Fixes
- Kafka — the Kafka consumer used by the connectors and query services no longer loses messages after a temporary handler failure. The indexing consumer was not affected (#3515).
- Google — the personal Drive and Gmail connectors keep the fresher OAuth token after the library refreshes it, and save refreshed tokens to settings, which ends a refresh loop (#3571).
- Web — stored ETag and Last-Modified values are read from the file record (#3622).
- Frontend — three wordings the locale pass changed are restored (#3610).
Security & authentication
- Service accounts — a person can no longer be given an address in the reserved service-account domain, on any of the four paths that set an email, and the service-account routes get the same rate limit as the token and OAuth app routes (#3612 — @shekharkadyan).
- Toolset OAuth callback — a failed agent access check is answered with JSON instead of a redirect to a caller-supplied address, which the Node API used to follow on the server (#3611 — @shekharkadyan).
- S3 — the bucket name and region are matched literally when a stored file URL is read back, so a bucket such as
my.bucketno longer also matchesmyxbucket(#3608 — @shekharkadyan).
Developer experience & infrastructure
- AWS EKS — S3 on EKS gets a SigV4 preload config map in the Helm chart, EKS values and docs updates, and a bucket purge test (#3634 — @abhishekgml1991).
- Tests and CI — a weekly sustained-load test for search and chat that fails on errors and p95 regressions (#3614); a frontend unit-test coverage minimum (#3577); the shared “test” logger is no longer silenced for later tests (#3613); storage tokens are minted for the user the test client acts as (#3623); chat stream mocks really end or stay open (#3624); a missing SMB folder reads as an empty listing in the integration tests (#3620) — all @shekharkadyan.
Full commit-level detail: GitHub release · Compare view