Repository navigation
Conversation
|
Claude finished @alukach's task in 16s —— View job ✅ No blocking issues — safe to merge. I read the latest commit (
Simplify (ponytail)
💰 Estimated review cost: $0.17 · 0m16s · 7 turns |
4 tasks done
alukach
added a commit
that referenced
this pull request
Oct 17, 2026
alukach
added a commit
that referenced
this pull request
Oct 17, 2026
alukach
added a commit
that referenced
this pull request
Oct 19, 2026
… edit and completion From the review on #58: - A key that can't be written to --out (or the path typed at the prompt) is shown instead, and under --json stays in the record, rather than lost after the API has issued it - --expires with a count too big for a date is a usage error, not a panic - expiry_label reads its date with time(), as the rest do Rebased onto main: - edit with no flags asks for the name from the current one, and --disable / --enable are flags only, as product edit's form (#62) leaves them; their effect is explained after the change - TAB completes service account IDs, owners and products, as #63's convention test requires; a new ID for create isn't completed, since shells would put a space after `OWNER--` Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
alukach
force-pushed
the
feat/service-accounts
branch
from
October 19, 2026 19:45
c4474a3 to
f8d455c
Compare
alukach
added a commit
that referenced
this pull request
Oct 19, 2026
Contributor
Author
|
Addressed in f8d455c, after rebasing onto
The rebase also needed two changes beyond the conflicts:
🤖 Generated with Claude Code |
…nd product access `source-coop service-account` lists, views, creates, edits and deletes service accounts, laid out as the web UI's page is: who it is, how it signs in, what it can reach. - `sign-in add/edit/remove` trusts GitHub Actions workflows (subjects built from --github and --branch/--tag/--environment, checked with GitHub as the web UI does) and issues, re-expires and revokes API keys, each shown once and never lost when saving it fails - `sign-in revoke-key` revokes a leaked API key read from stdin - `access set/remove` grants or ends product memberships - `usage` prints the web UI's workflow and API-key snippets - `create` prompts in the web form's order, with back, review and drafts - TAB completes service account IDs, owners and products Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
alukach
force-pushed
the
feat/service-accounts
branch
from
October 19, 2026 20:39
f8d455c to
a39a6c5
Compare
alukach
marked this pull request as ready for review
October 19, 2026 20:52
…rate access command From review on #58: - `edit --access ACCOUNT/PRODUCT=read|write|none` (repeatable) grants a product, changes its role or takes it away, the same shape `create --access` takes; already-so changes nothing, so a draft sent twice is safe - `edit` with no flags opens a form like `product edit`'s: the name and each product reached, "Grant a product…", then a review before saving - `edit --json` prints the account as `view --json` does, memberships too - the `access set` / `access remove` commands are gone (never released) - the README says how to list without the pager: --no-pager, SOURCE_PAGER=cat Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
alukach
added a commit
that referenced
this pull request
Oct 19, 2026
…w` does "Name" heads the field and "Can reach" the grants, each a product, its role, then what it was, with "+ Grant a product…" among them; the review before saving uses the same columns. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
alukach
added a commit
that referenced
this pull request
Oct 19, 2026
From the second review on #58: - --out and the "Save the key to a file" prompt only create a new file (`cache::write_new_file`: create_new, 0600, no directories made), so a mistyped path can't destroy one; the key is shown instead, as for any failed save - GH_TOKEN / GITHUB_TOKEN is only sent to api.github.com - a date given to --expires is at midnight UTC, as help and README now say - expiry_label parses its date directly Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
Author
|
Addressed in d956c47:
🤖 Generated with Claude Code |
- Always show a new key when the save prompt is cancelled - Only null revokes access in edit; accept read/write, reject unknown values - Keep earlier answers reachable when going back past the ID in create - Honour local_id from --from-file in create - Exit on Ctrl+C in the edit form's grant flow - Time out the GitHub repository lookup after 10s - Check sign-in before the first prompt in sign-in remove -i - Fetch memberships once per edit Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds
source-coop service-account, built against the draft service accounts API on source.coop'sfeat/api-service-accounts(OpenAPI). Its layout and wording follow the web UI's service account components (src/components/features/service-accounts/*): who it is, signs in with, can reach.Demos
Recorded against
demo/stub.py's made-up records (#59), hence thelocalhostURLs. The GitHub subject check is real: it asks api.github.com aboutsource-cooperative/source.coop. Each plays inline; click one for asciinema's player, where you can pause and copy text. To re-record them once #59 is in:cargo build && python3 -I demo/record.py demo/demos/service-accounts.py --upload \ --gif-base https://github.com/source-cooperative/source-coop-cli/raw/demo-assets/pr-58service-account list: an owner's service accounts, then as--jsonservice-account view: who it is, signs in with, can reach;--jsonaddstrustsandmembershipsservice-account createwith prompts: owner, name, ID, a GitHub workflow (checked with GitHub), an API key, a product grant, review, then saving the keyservice-account createfrom flags,--jsonservice-account list -i: open a record, go back, delete one from its screenservice-account edit:--disableand--enable(with the web UI's explanations), then a rename in the edit formservice-account delete: typed confirmation, then--yes --jsonservice-account sign-in addwith prompts (a workflow) and from flags,sign-in remove -i,sign-in revoke-keyservice-account viewwith API keys,sign-in add --key --out,sign-in edit -i(a new expiry) andsign-in remove key:HINT(revoke, typed back)service-account edit --access, then the edit form: take a product away, grant another, review and saveservice-account usage: pick a sign-in for its workflow, then--keyCommands
How it matches the web UI
--github OWNER/REPOwith--branch,--tagor--environmentbuilds the token subject, asGithubWorkflowFieldsdoes.owner@1/repo@2). It warns about custom subject templates and about repositories it can't see.GH_TOKEN/GITHUB_TOKENwhen set, so private repositories can be looked up too.usage: a line-for-line port ofservice-account-usage.ts. The tests check it against the web UI's own tests.aws-actions/configure-aws-credentials, orAWS_WEB_IDENTITY_TOKEN_FILEfor a key.credsis unchanged.create: it follows the form's order (owner, name, ID made from the name, workflows, products, review), with ↑/← back, drafts, a sign-in check before the first question, and re-asking only the fields the API rejects.IssueApiKeyDialog,ApiKeyListandIssuedApiKey, using the draft API's/accounts/{id}/keys(source.coop#665).--outwrites it to a0600file. On a terminal, you're offered a file to save it to; piped, it goes alone to stdout.viewlists keys by label and hint (key:a1B2c3), with when each was last used and when it ends. Revoked and expired keys are dimmed, and the list says when GitHub's secret scanning revoked one.key:HINTback, since a revoked key can't be restored.createoffers one "API key…", as the web form does.editopens a form like feat(product): edit opens a form of current values instead of asking which fields to change #62's product edit, laid out in a label column asviewis: the Name field, then Can reach over each product the account reaches with its role (Read, Read and write, or No access), Grant a product…, then a review before saving. Changed rows show what they were.--access ACCOUNT/PRODUCT=read|write|nonedoes the same from the command line, in the shapecreate --accesstakes. A role a product already has, or taking away access it doesn't have, changes nothing, so a draft sent twice does no harm.edit --jsonprints the account asview --jsondoes,membershipsincluded.--disableand--enableare flags only, as feat(product): edit opens a form of current values instead of asking which fields to change #62 left them for products, and they print the web UI's explanation of what they do.deleteasks you to type the ID back.my-org--nightly-sync) from the accounts whose service accounts you can list, and owners forlist. A new ID forcreateisn't completed, because bash and zsh would put a space aftermy-org--.Not in this PR
These are blocked on the draft API:
viewfinds the account by scanning its owner's listing.GET /accounts/{id}answers 404 for a service account unless you're an admin. There's aponytail:comment to switch to a direct fetch once the account's managers may read it.listshows no counts of workflows, keys and products per account, as the web UI does. That would take three extra calls per row unlessServiceAccountPagecarries them.POST /truststakes a GitHub-only body, so other identity providers would need API changes.sign-in add --issueris left out until the API takes one.These are left for later:
-irecord screen hasb/e/donly. Adding or removing sign-ins and access from it is a follow-up.Also changed
resource_commands_follow_the_cli_conventions). Without that, it would require-ionsign-initself; their leaf commands are still checked.main's sharedSite(--api-url/--proxy-url) and the helpers feat: manage members and invitations (member, invitation) #57 madepub(crate)inproduct.rs, so this PR doesn't changeproduct.rs.Test plan
cargo fmt,cargo clippy --all-targets -- -D warningscargo testandcargo test --features staging: 157 pass. The 17 new tests coveredit --accessgranting, changing and taking away access once each; the edit form renaming, taking a product away and granting another after a review (the wholeaskedlist);--expiresparsing, including counts too big for a date; a key that can't be saved being shown, or kept in the JSON, rather than lost; completing whole service account IDs from the owners you can list; issuing a key to a0600file, with--jsonnamingkey_fileand leaving out the key; one sign-in at a time; finding keys by hint, giving one a new expiry and revoking it (exit 5 for an unknown hint); a prompted revoke that asks for the typed hint; subject building and labels, usage snippets matching the web UI,createfrom flags and fully prompted with a workflow, a key and a grant (the wholeaskedlist),viewcomposing trusts, keys (live and revoked) and memberships (and exiting 5 when the account isn't found),sign-in remove's query and--yes, anddelete --yes.SOURCE_TOKENand a tempHOME:usage --keyand--subject, bad-ID usage error (exit 2),deleterefusing without--yes,--jsonerrors.🤖 Generated with Claude Code