Skip to content

🤖 feat: Share mode for CoderWorkspacePool claims (#153 PR 14) - #446

Merged
ThomasK33 merged 16 commits into
mainfrom
pool-share-mode
Nov 1, 2026
Merged

ThomasK33 merged 16 commits into
mainfrom
pool-share-mode

Conversation

@ThomasK33

@ThomasK33 ThomasK33 commented Oct 31, 2026 •

Copy link
Copy Markdown
Member

Summary

Plan PR 14 of #153: Share mode for CoderWorkspacePool. A claim on a pool with claims.mode: Share names one Coder user in spec.share.user. The operator binds a ready workspace as in Reserve mode, then gives that user the Coder use role on it (apps, SSH, start, stop; never delete). The operator's token is a site owner, and Coder lets a site owner share where the pool owner could not, so the controller enforces the organization's sharing setting and the admin's per-owner shareGroupIDs itself. It never changes a sharing setting.

Refs #153

Background

Coder has no ownership transfer for normal workspaces, so pool workspaces stay with the pool owner (plan 3.1, 3.2). The branch is rebased on main with PR 13 (#445) and PR 15a (#447, unclaimed-age refresh and idle reaping). Reserve mode (PR 12, #441) serves automation that already holds the owner's credentials. Share mode serves people, as an admin opt-in per owner (decision D2), because every claimant can act as the pool owner if the template exposes the owner's token (threat T3).

R3: groups need a license (design decision, agreed before implementation)

Every Coder group route needs Premium. In v2.37.2 and v2.37.3, /api/v2/groups* and /organizations/{org}/groups run templateRBACEnabledMW (enterprise/coderd/coderd.go:514-520,631-641). On the unlicensed Kind Coder, GET /api/v2/groups/<org ID> and POST /organizations/<org>/groups both answered 403 "Template RBAC is a Premium feature. Contact sales!" (probed live). The ACL routes and GET/PATCH /organizations/{org}/settings/workspace-sharing have no license gate (coderd/coderd.go:1884-1888, enterprise/coderd/coderd.go:494-497).

So a shareGroupIDs entry equal to the template's organization ID counts as that organization's Everyone group, checked as organization membership with no group read. Only the template's organization counts: another organization's ID is read like any group. Coder source for the equivalence (v2.37.3, same in v2.37.2):

  • coderd/database/queries/groups.sql:169-176: InsertAllUsersGroup creates the group Everyone with id = organization_id.
  • coderd/database/modelmethods.go:849-851: Group.IsEveryone() is g.ID == g.OrganizationID.
  • coderd/database/dump.sql:2501-2533: view group_members_expanded adds every organization member to the group whose ID is the organization ID.

Any other group is read with GET /api/v2/groups/{id}. A 403 (no license) or 404 refuses the user, and the message names the group. Other failures wait as CoderUnavailable.

Implementation

API (generated deepcopy, CRDs, install bundle, and reference docs updated):

  • CoderControlPlane.spec.workspacePools.owners[].shareGroupIDs: lower-case UUIDs, at most 16. Empty means Share mode is off for the owner.
  • CoderWorkspacePool.spec.claims.mode accepts Share (still immutable).
  • CoderWorkspaceClaim.spec.share.user: a Coder username (at most 32 characters) or a lower-case UUID, never the prebuilds system user. status.sharedUserID reports the user while Coder shows the share.
  • CoderWorkspacePoolMember.status.sharedUserID (lower-case UUID, prebuilds user refused) and a new Shared condition.

Share policy (internal/controller/coderworkspacepool_share.go, plan 6.8):

  • Organization setting, read right before each decision: everyone allows, service_accounts allows only a service-account owner, none or any other value refuses (ShareNotAllowed). A deployment-wide disable (sharing_globally_disabled) refuses too. Coder v2.37 then also answers none.
  • Named user: exists (ShareUserNotFound), not the prebuilds user, active, a member of the template's organization, and in one of the owner's groups (ShareUserNotEligible).

Pool reconciler:

  • In Share mode, the policy runs at resolve, so a misconfigured pool reports ShareNotAllowed and builds nothing. Its waiting claims then wait with the same reason and are no demand, so a pool at replicas: 0 deletes the unclaimed members it built for them.
  • Before a bind, the pool checks each waiting Share claim's user against the control plane read without the cache, because a bind cannot be undone. A refused claim stays Pending with its reason, never binds, and is no demand, so the pool builds no workspace for it. A claim whose check could not read Coder still counts as demand, so an outage does not delete the member built for it. Any claim author can add refused claims, so the pool reads each listed group once per reconcile, keeps a refusal for one poll (60 s), and stops the checks at Coder's 429: a refused claim costs about one Coder request per minute.
  • A claim whose spec.share does not match the pool mode never binds, is no demand, and is Stalled with ClaimModeMismatch.
  • A bound Share claim is Ready only while the member's Shared condition is True. It is Stalled with ShareRefused or ShareRemoved, else SharingWorkspace.

Member reconciler (plan 6.2 step 11 rule 2), at every poll after the one bind extension and the identity guard read, and at once after a control plane change:

  1. Reads the workspace ACL, and checks the share policy on fresh inputs: the control plane without the cache, the owner, the organization setting, and the user. After the first check it uses the user ID stored in status.sharedUserID, never the claim's username again, so a rename or a reused username never moves the share.
  2. The ACL lists the user and the policy allows it: Shared=True (also after a crash that lost the status write). The operator writes only use. A role that a person changed later, such as admin, still counts, and the operator never writes it back.
  3. The ACL lists the user, but the policy no longer allows it (the user left every listed group, shareGroupIDs is empty, the owner left owners, the user is suspended): one write {"user_roles":{"<id>":""}} removes the share, Shared=False ShareRevoked (ShareRevoking until the removal works). A Coder read that fails keeps the share. Coder applies a share removal only when the workspace restarts, and the operator does not restart or stop it, so the message says that the user keeps access until then and how to end it at once (restart or stop the workspace, or delete the claim).
  4. The member saw the share before and the user is gone from the ACL: ShareRemoved, with the same note on access until a restart. After ShareRevoked or ShareRemoved the operator never shares again.
  5. Not shared yet and allowed: it stores the user ID before the write, then sends PATCH /api/v2/workspaces/{id}/acl with exactly {"user_roles":{"<id>":"use"}}. A refusal, a 403 included, is ShareRefused, and the member keeps polling every 60 s.

The member starts the claim informer in its own SetupWithManager, because it reads its claim through the cache.

Kind phase P9 (hack/e2e-workspace-pool.sh, after P8, before the final cleanup): a second password user, created and logged in once, as the Share user. A Share pool without shareGroupIDs reports ShareNotAllowed and makes no member. With a non-Everyone group, the claim waits with ShareUserNotEligible and the message names the group. With the organization set to none, the pool reports ShareNotAllowed and the claim does not bind. With everyone and the organization ID, the claim is Bound and Ready, GET /acl lists only the Share user with use, the Share user's token reads the workspace, and a delete build with that token answers 403. When the admin then empties shareGroupIDs, the member removes the share: the ACL is empty and the claim reports ShareRevoked. The phase then deletes its claim and pool, checks their workspaces deleted in Coder, and restores the sharing setting. The final cleanup still restores spec.workspacePools. The driver keeps its two Coder users for a rerun. P1 now creates its owner through the same password_user helper.

Offline stubs (hack/e2e-workspace-pool_test.sh): the fake Coder and controller model Share mode, and 7 new negative controls each break one P9 behavior (policy ignored without groups, group not checked, none ignored, admin instead of use, Share user cannot read, Share user can delete, share not revoked). The leak check covers both users' passwords and sessions.

Docs: a "Share a workspace with a person" section in docs/how-to/workspace-pools.md: the admin opt-in, the organization ID as Everyone (every active member, no license), other groups need Premium (403, group named), the sharing setting the controller never changes, Ready only while Coder shows the share, subdomain apps and a wildcard access URL for the shared user's apps, access that lasts until the workspace restarts or stops after a share removal, and the warning that every claimant can act as the pool owner (owner token, external auth, Git SSH key), that anyone who can create pools on a control plane can act as every owner it lists, and that maxWorkspaces counts per control plane.

Plan deviations

  • Plan 6.8 item 3 reads every group. The template organization's ID skips the read (R3, above).
  • Plan 6.2 step 11 rule 3 lets a bound member only watch for deletion. A Share member also reads the ACL every poll (one more request per minute per bound Share member), so Ready follows Coder and a forged sharedUserID never marks a claim Ready. An independent pre-PR reviewer found both gaps.
  • Plan 5.4 lists only sharedUserID on the member. The Shared condition separates "the share happened" from "Coder shows it now".
  • The plan never removes a share. The member removes its own share once the policy no longer allows it (Codex security, first round), so removing a user from the listed groups, or the owner's consent, removes the share within a poll. Access ends only when the workspace restarts or stops, because Coder applies a share removal only then (Shared workspaces). The operator does not restart or stop the workspace (🤖 CoderWorkspacePool Share mode: optionally stop the workspace when a share is revoked #450 tracks an opt-in stop). It costs 4 more Coder reads per minute per shared member (measured from the code: ACL, owner, user, organization setting; the how-to's cost table has the row).

Validation

  • Local gates on the PR head (make test-scripts on 4d2652b8; hack/ has not changed since): make verify-vendor, make build, make lint, make test, make test-integration, make codegen manifests docs-reference build-installer (no diff), make docs-check reference part plus mkdocs build --strict in nix develop, markdownlint-cli2 and cspell on docs/**, actionlint: all passed. make test-scripts: see the comment below.

  • envtest (new file coderworkspacepool_share_test.go), each through Reconcile with the real codersdk against the fake Coder:

    • Shares by username and by UUID with exactly one ACL write of use, claim Ready only after it.
    • T13: each shareable_workspace_owners value at resolve and right before the ACL write (everyone, service_accounts with a password owner and with a service-account owner, none, an unknown value), no shareGroupIDs, owner no longer listed, Coder's 403.
    • T12: a listed group without the user, a real group on a licensed fake, the same group without a license, another organization's ID, suspended and dormant users, a user outside the organization, an unknown user, the prebuilds user by username.
    • Idempotent: later reconciles never write the ACL again.
    • Crashes: a bind with no member reconcile yet shares once. An ACL write whose status write is lost is recognized from the ACL without a second write, also after the user left the group. After a lost status write or a write without effect, a renamed user keeps the share and a new user with the old name never gets it, and a no-longer-eligible stored user is refused.
    • Coder drops the share after the org setting tightens: ShareRemoved, no second write after the setting is relaxed again. A forged Shared status is caught by the ACL read.
    • Withdrawn policy: the user leaves every listed group (also after a lost status write), shareGroupIDs emptied, the owner removed, the user suspended. Each removes the share with one write of "", reports ShareRevoked, and never shares again after the policy allows it again. A failed policy read keeps the share, and a failed removal is ShareRevoking until a retry works.
    • Mode mismatch both ways, demand kept during a group-read outage, no demand while the pool reports ShareNotAllowed, and the claim informer under a strict cache.
    • A person changes the shared user's role to admin: the claim stays Ready, no write back, and a withdrawn policy still removes the entry.
    • The fake's sharing-settings write route fails the test on any call (T6).
  • Mutation checks, each made a named test fail:

    • Policy check returns nil: TestPoolShareNotAllowed, TestPoolMemberChecksSharePolicyBeforeACLWrite.
    • Any group admits the user: TestPoolChecksShareUserBeforeBind/listed_group_without_the_user.
    • Any of the user's organizations counts as Everyone: TestPoolChecksShareUserBeforeBind/another_organization's_ID.
    • Prebuilds refusal removed: TestPoolChecksShareUserBeforeBind/prebuilds_user.
    • Refused claims counted as demand: TestPoolChecksShareUserBeforeBind, TestPoolRefusesClaimOfOtherMode.
    • Unreadable claims dropped from demand: TestPoolKeepsDemandWhileShareCheckFails.
    • Retry checks the claim's username instead of the stored ID: TestPoolMemberShareKeepsItsUserAfterRename.
    • User ID not stored before the write: TestPoolMemberShareSurvivesLostStatus, TestPoolMemberShareKeepsItsUserAfterRename.
    • A removed share is not reported, or Ready trusts sharedUserID: TestPoolMemberReportsRemovedShare.
    • No removal when the policy is withdrawn, a second share after a removal, or a failed read that removes: TestPoolMemberRevokesWithdrawnShare.
    • The pre-bind check reads the cached control plane: TestPoolChecksShareGroupsWithoutCache. No deployment-wide disable check: TestPoolShareNotAllowed.
    • No group memo, no refusal memo, or no stop at 429: TestPoolBoundsShareChecksOfRefusedClaims.
    • Claim informer not started: TestPoolMemberSharesThroughManager.
    • Presence in the ACL requires the use role: TestPoolMemberEnforcesPolicyAfterRoleChange.
    • Waiting claims of a ShareNotAllowed pool still count as demand: TestPoolDropsShareDemandWhileShareNotAllowed, TestPoolShareNotAllowed.
  • Offline stubs: all 23 scenarios pass (2.5 min).

  • Kind (CI replica on a kind-dev.sh cluster, kindest/node v1.32.0, Coder v2.37.2 without a license, operator built from this branch, CI steps 7 to 28): the pool driver passed P1 to P9, then the lifecycle driver and the wrong-CA step passed.

    Phase Time
    P1 / P2 / P3 / P4 / P5 11 s / 11 s / 12 s / 12 s / 14 s
    P6 / P7 / P8 110 s / 7 s / 35 s
    P9 104 s
    cleanup 1 s

    After the first review round (head 1ea170cd, with the revocation step in P9), the pool driver passed again on the same cluster: P9 106 s, and the emptied shareGroupIDs removed the share in Coder at once (the member watches its control plane). The Share claim was Ready 60.4 s after the driver allowed sharing again: the pool reads the setting at its next poll, once a minute. P9 adds about 1.7 minutes to the Kind job (R6), well below the 10-minute limit of decision D8.

  • CI's E2E job on 2eaa8878 (before the rebase on 🤖 feat: replace old unclaimed pool workspaces and reap idle claimed ones, both opt-in (#153 PR 15a) #447) ran P1 to P9: P9 passed in 88 s, and the Share claim was Ready 58.8 s after the driver allowed sharing again.

  • R3 checked on v2.37.2 without a license: groups answer 403, the ACL write, the ACL read, and the sharing setting work, and the Share user's delete build answers 403.

  • Dogfood (recording, a screenshot of the Share user's Coder UI, coder ssh <owner>/<workspace> as the Share user) follows in a comment.

Risks


Generated with xum • Model: anthropic:claude-opus-5-5 • Thinking: xhigh

@ThomasK33

Copy link
Copy Markdown
Member Author

@codex security review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 31, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-01T00:33:04.597018Z 2924f36 Manual request
🔒 Security Review ✅ Completed 2026-11-01T00:35:46.279977Z 2924f36 Manual request

Security findings

Advisory findings (6)

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛡️ Codex Security Review

Here are some automated security review suggestions for this pull request.

Reviewed commit: 06b99befc8

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@ThomasK33

ThomasK33 commented Oct 31, 2026 •

Copy link
Copy Markdown
Member Author

Dogfood: Share mode by hand on a kind-dev.sh cluster

Cluster: ./hack/kind-dev.sh up with kindest/node v1.32.0, the CI bootstrap (CloudNativePG, Coder v2.37.2 without a license, agent fixture), and the operator image built from this PR's head 06b99bef. Owner e2e-pool-owner, Share user e2e-share-user, pool dev-workspaces (claims.mode: Share), claim bob-dev. The pool driver passed P1 to P9 on the same cluster first (P9 104 s).

Terminal recording (asciinema, rendered with agg at half speed, idle gaps capped):

dogfood.mp4

What it shows, in order:

  1. Coder has no license (template_rbac: false), and the organization's sharing setting is everyone.
  2. The admin sets the owner's shareGroupIDs to the organization ID, its Everyone group.
  3. The Share pool is Ready with 1 workspace. The claim for e2e-share-user is Bound and Ready with sharedUserID, 1 s after it was created. GET /acl lists only e2e-share-user with use.
  4. As e2e-share-user: a read of the workspace works, coder ssh e2e-pool-owner/<workspace> runs a command in the workspace pod, and a delete build answers 403 "You do not have permission to delete this workspace."
  5. The admin sets organization sharing to none. Coder drops the share, and 38 s later the claim is Stalled with ShareRemoved. After the admin sets everyone again, the claim stays ShareRemoved and the ACL stays empty: the operator never shares a second time.
  6. Deleting the claim and the pool deletes their workspaces in Coder: the owner has no workspace left.

e2e-share-user's Coder UI, with the filter shared_with_user:me: the workspace of e2e-pool-owner, shown with the shared icon.

Coder workspaces list of e2e-share-user filtered to shared_with_user:me: one running kwp- workspace owned by e2e-pool-owner

The shared workspace's page as e2e-share-user: running, with Terminal and SSH.

Coder workspace page of the shared kwp- workspace as e2e-share-user, running, with Terminal and Connect via SSH

The same list after the cleanup: nothing is shared with e2e-share-user anymore.

Coder workspaces list of e2e-share-user filtered to shared_with_user:me after the cleanup: no results

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 06b99befc8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

ThomasK33 added a commit that referenced this pull request Oct 31, 2026
…ows it (#153 PR 14)

Codex security review on #446: a user removed from every shareGroupIDs group, or an owner
whose consent the admin withdrew, kept the use role. The member now checks the share policy
at every poll and removes the operator's share once it fails, reports ShareRevoked, and never
shares again. A failed Coder read keeps the share.

Change-Id: Ib2c4111eaa8369f34f1f3a196e1b7325641bee50
Signed-off-by: Thomas Kosiewski <tk@coder.com>
@ThomasK33

Copy link
Copy Markdown
Member Author

@codex review

@ThomasK33

Copy link
Copy Markdown
Member Author

@codex security review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Swish!

Reviewed commit: 4d2652b858

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛡️ Codex Security Review

Here are some automated security review suggestions for this pull request.

Reviewed commit: 4d2652b858

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

ThomasK33 added a commit that referenced this pull request Oct 31, 2026
Codex security review on #446: any claim author can add claims that the policy refuses, and
the pool checked each on every reconcile, with a user read and a read of each listed group,
through its one worker. The pool now reads each group once per reconcile, keeps a refusal for
one poll, and stops the checks at Coder's 429.

Change-Id: If96ac4f7c5495723c14577f841cfdcf92be462f8
Signed-off-by: Thomas Kosiewski <tk@coder.com>
@ThomasK33

Copy link
Copy Markdown
Member Author

@codex review

@ThomasK33

Copy link
Copy Markdown
Member Author

@codex security review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7179222034

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛡️ Codex Security Review

Here are some automated security review suggestions for this pull request.

Reviewed commit: 7179222034

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@ThomasK33

Copy link
Copy Markdown
Member Author

@codex review

@ThomasK33

Copy link
Copy Markdown
Member Author

@codex security review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛡️ Codex Security Review

Here are some automated security review suggestions for this pull request.

Reviewed commit: 2eaa88780f

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. More of your lovely PRs please.

Reviewed commit: 2eaa88780f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

…embers (#153 PR 14)

CoderControlPlane spec.workspacePools.owners[].shareGroupIDs turns on Share mode for an owner.
CoderWorkspacePool claims.mode accepts Share. CoderWorkspaceClaim gets spec.share.user and
status.sharedUserID, and CoderWorkspacePoolMember gets status.sharedUserID and the Shared
condition. Generated deepcopy, CRDs, install bundle, and API reference.

Change-Id: I946f8f3d0e916d3baa5819e8b4c8ae54712964fb
Signed-off-by: Thomas Kosiewski <tk@coder.com>
…drops on a tightened setting (#153 PR 14)

Change-Id: I425ef9f9053e6fbef6057d5661d05dadd76c7f51
Signed-off-by: Thomas Kosiewski <tk@coder.com>
…organization's sharing policy (#153 PR 14)

The pool checks the policy at resolve (ShareNotAllowed) and the claim's user before a bind
(ShareUserNotFound, ShareUserNotEligible). The member checks both again right before its
ACL write, stores the user ID before the write, grants only use, and reports the share from
Coder's ACL in the Shared condition (ShareRefused, ShareRemoved). It never changes a sharing
setting and never shares a second time.

Change-Id: Ib876665ca9350127372083d1269d71a46dc668be
Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: If0efd89adaad2590ce35a700ed21aafcdd8767c2
Signed-off-by: Thomas Kosiewski <tk@coder.com>
…e stubs for it (#153 PR 14)

Change-Id: Ife15ccf6c8bdbcb7b3d06251e898c089174b582d
Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: I0d2ce2869eb4cfea5a327eaeb167f0295ae1ca9e
Signed-off-by: Thomas Kosiewski <tk@coder.com>
…ows it (#153 PR 14)

Codex security review on #446: a user removed from every shareGroupIDs group, or an owner
whose consent the admin withdrew, kept the use role. The member now checks the share policy
at every poll and removes the operator's share once it fails, reports ShareRevoked, and never
shares again. A failed Coder read keeps the share.

Change-Id: Ib2c4111eaa8369f34f1f3a196e1b7325641bee50
Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: I9c392a6dbc1a8286e19285e03ca6019950126e47
Signed-off-by: Thomas Kosiewski <tk@coder.com>
…and honor a deployment-wide sharing disable (#153 PR 14)

Change-Id: Ie5a37cd9a00218c468698450a4c5c5c66ddc501a
Signed-off-by: Thomas Kosiewski <tk@coder.com>
Codex security review on #446: any claim author can add claims that the policy refuses, and
the pool checked each on every reconcile, with a user read and a read of each listed group,
through its one worker. The pool now reads each group once per reconcile, keeps a refusal for
one poll, and stops the checks at Coder's 429.

Change-Id: If96ac4f7c5495723c14577f841cfdcf92be462f8
Signed-off-by: Thomas Kosiewski <tk@coder.com>
…the rest

Change-Id: I70abee16dd8b1fc8426a2a872a6c9bed52e9913b
Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: I5e227e8c7b8b5931c1aaff0792e5b9cf6ae7e5e7
Signed-off-by: Thomas Kosiewski <tk@coder.com>
…hile sharing is not allowed (#153 PR 14)

A person can change the shared user's role from use to admin in Coder.
The member now finds the stored user in the ACL with any role, so it
keeps reporting the share, never writes the role back, and still removes
the share once the policy no longer allows it. ShareRemoved now means
the user is gone from the ACL.

While the pool's resolve reports ShareNotAllowed, no claim of the pool
can get its share. Each waiting claim now waits with that reason and is
no demand, so a pool at replicas 0 deletes the unclaimed member it built
for the claim.

Codex review, round 3.

Change-Id: Id79f117386b4a5e8c5586969fcbd3fdcc6b39f2e
Signed-off-by: Thomas Kosiewski <tk@coder.com>
Members make no Coder call once the control plane's delete starts (plan
6.5 item 3), so they stop checking and removing shares. Tell admins to
delete the Share claims first to end every share.

Change-Id: I96bcde3fb0c4f0d6ad659e1c47100f4b3459da9e
Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: I46a2c1e70bf319585cdb851ae991c132ff66bc5a
Signed-off-by: Thomas Kosiewski <tk@coder.com>
@ThomasK33

Copy link
Copy Markdown
Member Author

@codex review

@ThomasK33

Copy link
Copy Markdown
Member Author

@codex security review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛡️ Codex Security Review

Here are some automated security review suggestions for this pull request.

Reviewed commit: 58c21ecb55

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 58c21ecb55

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread docs/how-to/workspace-pools.md Resolved
…d shared users open only subdomain apps

Coder applies the removal of a share only when the workspace restarts,
and the operator does not restart or stop it. The ShareRevoked and
ShareRemoved messages now start with that, before the reason, because
the claim keeps only the first 256 bytes, and they tell the admin how to
end the access at once. The how-to says the same, and that a shared
user can open only subdomain apps on a deployment with a wildcard access
URL. #450 tracks an opt-in operator stop.

Codex review on 58c21ec.

Change-Id: I35b28230ebfacb626ccfca5ca998f11143df4f4f
Signed-off-by: Thomas Kosiewski <tk@coder.com>
@ThomasK33

Copy link
Copy Markdown
Member Author

@codex review

@ThomasK33

Copy link
Copy Markdown
Member Author

@codex security review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. What shall we delve into next?

Reviewed commit: 2924f36b4b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛡️ Codex Security Review

Here are some automated security review suggestions for this pull request.

Reviewed commit: 2924f36b4b

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

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.

1 participant