Skip to content

feat(team): share projects with members and invite by email - #276

Merged
vsilent merged 1 commit into
mainfrom
feature-team-projects
Oct 11, 2026
Merged

vsilent merged 1 commit into
mainfrom
feature-team-projects

Conversation

@vsilent

@vsilent vsilent commented Oct 11, 2026

Copy link
Copy Markdown
Collaborator

A project owner on the Team plan can invite people by email or add them by user id. A project has 5 seats: the owner, every member and every pending invitation that has not expired. Invitations live 7 days, store only a token hash, and are accepted by the signed-in account whose confirmed email is the invited one. The plan is checked when inviting, so members keep access if the owner later leaves Team; an unknown plan is refused, never treated as Team.

Roles: a member works on the stack like the owner (view, change apps, deploy, roll back, run agent commands). A viewer sees the project in the shared list and its deployments. Only the owner manages secrets, deletion, protection, members and invitations. No access answers exactly like a missing project (404); not enough role answers 403.

A member deploys on the owner's behalf: the owner's saved cloud, servers, SSH keys and quota, with everything recorded under the owner. The owner's address comes from the internal user lookup; if it cannot be read, the deploy is refused.

Tests: project_team_seats covers the feature scenarios, the project route sweep now checks every route per role, and both security sweeps include the new routes. Two viewer expectations change from 404 to 403 because a viewer has access to the project but not to the stack.

Claude-Session: https://claude.ai/code/session_012TKZy6f5shPzM9WLdswH6f

A project owner on the Team plan can invite people by email or add them
by user id. A project has 5 seats: the owner, every member and every
pending invitation that has not expired. Invitations live 7 days, store
only a token hash, and are accepted by the signed-in account whose
confirmed email is the invited one. The plan is checked when inviting, so
members keep access if the owner later leaves Team; an unknown plan is
refused, never treated as Team.

Roles: a member works on the stack like the owner (view, change apps,
deploy, roll back, run agent commands). A viewer sees the project in the
shared list and its deployments. Only the owner manages secrets, deletion,
protection, members and invitations. No access answers exactly like a
missing project (404); not enough role answers 403.

A member deploys on the owner's behalf: the owner's saved cloud, servers,
SSH keys and quota, with everything recorded under the owner. The owner's
address comes from the internal user lookup; if it cannot be read, the
deploy is refused.

Tests: project_team_seats covers the feature scenarios, the project route
sweep now checks every route per role, and both security sweeps include
the new routes. Two viewer expectations change from 404 to 403 because a
viewer has access to the project but not to the stack.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012TKZy6f5shPzM9WLdswH6f
@vsilent
vsilent merged commit a76bfcf into main Oct 11, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants