Skip to content

agents: revoke a connection by actor (MARSOHS-2183) - #2094

Merged
DO-rrao merged 2 commits into
mainfrom
jkosanam/connections-revoke-by-actor
Nov 3, 2026
Merged

DO-rrao merged 2 commits into
mainfrom
jkosanam/connections-revoke-by-actor

Conversation

@jkosanam

@jkosanam jkosanam commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Summary

doctl harness-runtime connections revoke accepts only the connection id, which the server assigns. A user who knows the actor has to run connections list --actor and copy the id first. Revoke now also takes --actor, looks up that actor's connection for the provider, and revokes it.
Jira: MARSOHS-2183

Scope

 connections revoke <connection-id>        → DeleteConnection(id)            (unchanged)
+connections revoke --actor <actor>        → ListConnections(actor), then:
+  exactly 1 connection for <actor>        → DeleteConnection(id), "Revoked connection <id> for <actor>"
+  0 connections                           → exit 1, "no <provider> connection found for actor <actor>"
+  2 or more                               → exit 1, lists the ids, "revoke one by id"
+connections revoke <id> --actor <actor>   → exit 1, "pass either a connection id or --actor, not both"

Blast radius

🟡 Services: doctl (harness-runtime connections revoke) · Customers: new opt-in --actor flag; revoke by id behaves as before.

Rollout

  • Rollback: revert; the change ships with the next doctl release and holds no state.

Decisions

  • With more than one connection for the actor, revoke refuses instead of picking one, so it can never revoke a connection the user did not mean. (connectionIDForActor)
  • The lookup reads every page of the list and stops at the second match; one match on page 1 does not prove there is no other. After 50 full pages it refuses rather than decide on a partial read.
  • Only list rows whose actor matches exactly are candidates, so a server filter that also returns alice-bot for alice cannot cause a wrong revoke.
  • The lookup is in doctl: the API already filters connections by actor and deletes by id, so no server change is needed.

Evidence

New revoke tests (by actor, none, several, other actor's row, a second match on page 2, the page cap, id plus --actor, 501 on lookup) pass; go test ./commands/... ./do/... passes except TestRegistryLogin and TestRegistryLogout, which fail the same way on main. Not run: against a live environment.

`harness-runtime connections revoke` accepted only the connection id.
That id is assigned by the server, so a user who knew the actor had to
run `connections list --actor` first and copy the id. Revoke now also
takes `--actor`: it looks up the actor's connection for the provider
and revokes it. It refuses when the actor has no connection or more
than one, and when both an id and `--actor` are given. Revoke by id is
unchanged.

Blast radius: doctl harness-runtime connections revoke; new opt-in
--actor flag, existing usage unchanged.
Rollback: revert; no state or stored data is involved.

MARSOHS-2183

Co-authored-by: Cursor <cursoragent@cursor.com>
@@ -93,12 +93,15 @@ This is the actor-scoped flow. The older ` + agentCLI + ` auth <provider> comman
AddStringFlag(cmdGet, doctl.ArgAgentConnProvider, "", "github", "External provider")
cmdGet.Example = agentCLI + ` connections get ` + "`<connection-id>`"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Right now, connectionIDForActor only reads the first page of results (PerPage: 100). Since the API is paginated, an actor with more than 100 connections might have exactly one result on the first page, with the rest appearing on subsequent pages. If that happens, the command will go ahead and revoke that first connection, which breaks the safety guarantee that it should refuse when there are multiple connections.

@jkosanam jkosanam Nov 2, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 8af7f48: connectionIDForActor now reads every page and counts matches across all of them

The actor lookup read only the first page of connections. One match
on page 1 was then revoked, even when a later page held another
connection for the same actor, so the "refuse when there is more than
one" rule did not hold. The lookup now reads every page and stops
early once it finds a second match. If the server keeps returning full
pages past a cap of 50, revoke refuses instead of deciding on a
partial read.

MARSOHS-2183

Co-authored-by: Cursor <cursoragent@cursor.com>
@DO-rrao
DO-rrao merged commit df15a9b into main Nov 3, 2026
6 checks passed
@DO-rrao
DO-rrao deleted the jkosanam/connections-revoke-by-actor branch November 3, 2026 05:27
BadhriDO added a commit to BadhriDO/doctl that referenced this pull request Nov 3, 2026
Resolves the conflict with digitalocean#2094 (revoke a connection by actor) in
commands/agent_connections.go: keep connectionIDForActor from main, and
this branch's completeConnectionAuth comment, which now also covers
reconnect.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

3 participants

⌂ 换网址