New teammates arrive ready to work
- Joining a workspace puts the new member in its default channels and opens the first one with the message box ready. Until an admin chooses others under Admin → General → Default channels, that's #general, followed through a rename. Every way in does this: an invitation, Google, GitHub, single sign-on, LDAP and SCIM. People SCIM creates inactive are welcomed when they start.
- Admin → Invitations says where each invitation stands: live (with the days its link has left), expired or joined, with its link to copy. An invitation with no expiry lasts a week. Inviting someone already in the workspace, or already invited, says so instead of sending a second email. Only admins renew an expired invitation; members can invite up to 50 people a day.
- The invitation email names who invited the person and to which workspace, and a reply reaches the inviter. The inviter's name is no longer in the subject. The admin is told whether the email went, and if not, why: email isn't set up, the provider refused it (with its reason), today's limit is used up, or the provider didn't answer in time. The link is shown either way.
- Names in any language. Sign-up, profiles and identity providers share one rule for a person's name: letters in any script, spaces, apostrophes, hyphens and full stops, up to 60, stored in a single normal form. Everyone gets an @handle made from their name, and can change it in their profile; everyone, here, channel, all and admin are reserved.
- One person, one account. Addresses are matched without regard to letter case everywhere (migration 203). Addresses with characters outside plain ASCII are refused at every way in rather than folded onto someone else's.
- Signing up with an invitation for an address that already has an account is refused with "sign in instead"; it no longer sets a new password on that account. Migration 204 closes invitations whose person is already a member.
- An allow-list entry like
@acme.comadmits people who sign in with Google accounts of that Google Workspace domain. GitHub never admits by a domain entry. Public mail domains (gmail.com, outlook.com and others) are refused, and the audit log names the entries added and removed. - The setup checklist puts Set up email before Invite your team, and its import step names monday.com. A member in no channel sees Join #general on Home.
Sign-in says why
- A refused sign-in says why on the sign-in page: cancelled at the provider, left open too long, an expired invitation, an address the provider hasn't verified, an address outside plain ASCII, not invited, or no free seat.
- GitHub sign-in accepts any verified address on the account that the workspace knows, not only the primary one.
AUTH_EMAIL_DISABLED=truenow turns passwords off: the sign-in page hides them, password sign-up is refused, and only admins can still sign in with a password, as the way back in if single sign-on breaks. If nothing else would let members in, the server logs a warning at startup and the admin system check fails. See Before you update.- OIDC providers that send
email_verifiedas text, such as Amazon Cognito, can sign people in.
Single sign-on, LDAP and SCIM
- SAML takes one command:
make saml-certmakes the certificate and key in./saml, which the shipped compose file mounts; thenmake restart-api. It works when Docker created./samlas root. - LDAPS can trust your company's own certificate authority: put its PEM in
./ldapand setLDAP_CA_CERT=/app/ldap/<file>. - The directory's admin groups work both ways: someone in a group listed in
LDAP_ADMIN_GROUPSbecomes an admin when they sign in, and a directory-managed admin taken out of those groups stops being one. Groups are named by their name ("OneCamp Admins") or full DN. - Two-step sign-in is asked for after an LDAP password too.
- A directory entry with no email address is refused with a message saying to add one, instead of being given a made-up address.
OIDC_ENABLED,SAML_ENABLED,LDAP_ENABLEDandLDAP_USE_TLSaccept true, 1, yes or on, in any case, and read the same everywhere. A provider that can't be set up at startup says why in the log.- SCIM adopts a person an import already brought in (same id, history kept) instead of failing or making a second account. Its documentation link is onemana.dev/docs/single-sign-on.
- An explicit
ONECAMP_MANAGEDvalue wins over the mark stored at hand-over.
Imports
- When an import finishes or fails, its admin is told, and offered Invite the N people who came across, with the seats the plan has left and how many invitation emails can go today. The rest can be copied from Admin → Invitations. A placeholder person's profile offers Invite to the workspace. Someone whose invitation expired is offered again.
- The Jira project, Todoist project or Asana workspace you pick is all that comes across, and a Jira project brings its own people and category. Asana asks which workspace instead of guessing.
- Every import has a way forward: a refused or unreadable token offers Reconnect; a failed import can be planned or run again; an import waiting to be planned can be discarded, and one left for a day is set aside (
IMPORT_PENDING_TTL_HOURS); a provider's pause, such as monday.com's daily limit, says when it lifts. - An import can't be started twice: pressing Run twice, or planning it again while it starts, starts it once ("This import changed in the meantime"). An import discarded while its file uploads stays discarded.
- Every provider's progress updates live, and your imports are listed before you pick a provider.
- Slack: imported messages come across (every one failed before); finalising, starting, finishing and cancelling work; Slack's #general goes into your #general while that holds only its welcome post, never into one shared with guests; channels archived in Slack are archived; the importing admin leaves private channels they weren't in, and admin of each passes to its Slack creator; the upload limit shown is the server's.
- Import errors never keep a provider's key or token.
- The setup steps say what each provider needs today: a Trello key made through a Power-Up, and a classic Jira API token.
Guests
- What a guest writes reaches the team, at most once per channel, thread or doc every five minutes: a message notifies members as their channel settings say; a thread reply notifies its author and repliers; a doc comment notifies the doc's creator and editors.
- Each kind of guest write has its own limit, per address and per link; joining a meeting and opening a live doc or board are limited per address only.
- A guest page says "This link is no longer available" only when the link is gone. When the server is busy or unreachable it says so, and keeps trying less and less often, never sooner than the server asks.
- A guest can't post into an archived channel.
- A shared doc or board's page shows its name. Project links start on Can see and comment. While guest access is off, the admin's card lists links as paused.
- Opening a link is recorded in the audit log once per half hour per link and guest, not on every refresh.
AI agents stay within what the person who asked can reach
- A run someone else started (a DM, a mention, an assigned task, a follow-up) reads and changes only what both that person and the agent's owner can reach. When the person lacks something, the agent says what in plain words. Before, every tool ran with the owner's access for anyone who could message the agent.
- An agent bound to an event hears only events in places its owner can see.
- Pausing or deleting an agent, or its owner leaving, stops it mid-run.
code_pris proposed to the person whose GitHub account it would push with, and runs as them.- An agent is added to a channel by its owner or an admin.
- Text from outside the workspace can't steer an agent: a message from an incoming webhook, a task filed by a public form and a comment synced from GitHub are asked for by nobody, so the agent answers in words and runs no tools. Agent replies on GitHub-linked tasks stay in the workspace.
- Agents can no longer be set up on GitHub events, and an agent bound to one before no longer runs on it. It can still be edited, paused or given another trigger.
rememberworks again. It and routines keep only the asker's own words; anything else is put to them first, in full, and only a yes keeps it. Remembered instructions are kept per person, and someone can cancel only their own routines.- On the first start after updating, routines that post where someone besides their owner can see, whose asker was never recorded, are paused, and their owners are told. Only the owner can turn one back on.
Security
- A private channel is joined only by being added to it; before, anyone could join one by its id.
- Live updates: the server now checks every subscription. Before, a signed-in client could subscribe to channels and conversations it wasn't in.
- Only a message's author can edit it, and only a thread reply's author can edit or delete it.
- Editing a doc takes edit access, changing who can see it takes its owner, and commenting takes being able to read it. A private doc's comments stay private, and a private doc no longer turns up in other people's AI search after an edit.
- Only an event's creator can delete it; invitees leave it instead.
- A group message's sender must be in the group. A forward goes only to places the sender may post in, and Also send to channel follows the channel's rules. A channel reminder posts only where its owner may post, checked each time it fires.
- Removing someone from a channel, project or team takes those places out of their search at once.
- Google and GitHub vouch for an address only once they've verified it.
- Sessions: each token says what it is; a two-step challenge is never a session; a refresh token is checked against the device's and rotated; changing a password ends your other sessions, and resetting it ends all of them.
- Rate limits count each visitor by the address the proxy saw, and keep holding while Redis is down. Before, everyone behind the proxy shared one limit, and the address could be forged.
- Imported people sign in only by joining, which takes a seat.
- The Resend webhook accepts only events Resend signed.
- Outbound requests (webhooks, apps, connectors, import downloads) refuse every internal address range, and a provider's token is sent only to that provider's host.
- A workflow hears only the channels and projects its owner can see.
- The UI Designer's generated screens are cleaned by parsing their HTML.
- Incoming webhooks stay rate-limited while Redis is down.
Installing and updating
- Messages, typing and presence arrive live on installed workspaces. Before, the shipped compose file routed live updates to port 8084 only, while browsers use 443.
- Calls work on a fresh install, and
make updaterepairs the call server's key on existing ones. make installalways prints where to create the first admin, andmake verifyno longer fails for a model engine nobody switched on.make logs SERVICE=web(or go-service, traefik, …) shows a service's log.- The installer at onemana.dev checks for Ubuntu or Debian before it starts, and asks for the edition in words.
Before you update: Migrations 200 to 204 run as part of make update. AUTH_EMAIL_DISABLED is read the right way round. If your .env sets it to true, passwords are now off for everyone but admins; remove it or set false to keep them. Set RESEND_WEBHOOK_SECRET to your Resend webhook's signing secret. Until you do, bounces and complaints aren't recorded. LDAP_ADMIN_GROUPS now works: people outside the groups it names stop being admins at their next directory sign-in. Check it names exactly the groups you mean. An @domain allow-list entry now admits only that domain's Google Workspace accounts, never GitHub; list exact addresses for anyone else. Nobody is signed out by this update: sessions from before it still refresh. Agents bound to GitHub events stop running on them. Routines that others can see but whose asker wasn't recorded are paused until their owner turns them back on.
Fixes
- Forwarding a message to a channel or a group chat works. It always failed before.
- A live doc no longer shows every paragraph twice after the collaboration server reloads it.
- A database hiccup no longer reads as "deleted" or "no such doc", and no longer resets workspace settings to their defaults, including right after a save.
- An AI column fill, or an agent updating a table row, changes only its own cells.
- A sent invoice keeps its number, even when taken back to draft (migration 201).
- A repeating task lands on your day in your time zone, and one set for the 31st comes back after February (migration 200).
- A deleted task stays deleted when a late change reaches it.
- A form stops filing tasks when the person who made it leaves the project.
- A comment on an unassigned task notifies its creator.
- Archive completed tasks works, and so does undoing a file archive.
- Rolling back an import that brought files finishes.
- Recordings: deleting, archiving and restoring one works, and a deleted recording is gone, transcript included.
- Backups wait for the whole graph; a dump that wrote nothing fails; restoring the oldest backup no longer deletes it first.
- With the worker profile on, each backend process connects to the live-update broker under its own name. Before, they kept disconnecting each other.
- A GitHub comment synced onto a task is credited to the linked OneCamp person, and an AI reply in a group chat notifies the group.