-
Notifications
You must be signed in to change notification settings - Fork 1
Mason/agents auth #61
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
| type AgentAuthCmd struct { | ||
| auth AgentAuthService | ||
| invocations AgentAuthInvocationService | ||
| browsers BrowsersService |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This field is declared but never used anywhere in the file. Consider removing it to avoid confusion.
| browsers BrowsersService | |
| type AgentAuthCmd struct { | |
| auth AgentAuthService | |
| invocations AgentAuthInvocationService | |
| } |
| } else { | ||
| pterm.Info.Println("(Opened in browser)") | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The polling loop doesn't check for context cancellation. If a user presses Ctrl+C, the loop will continue until the next API call fails. Consider adding a context check:
| } | |
| for time.Since(startTime) < maxWaitTime { | |
| select { | |
| case <-ctx.Done(): | |
| return ctx.Err() | |
| default: | |
| } | |
| state, err := a.invocations.Get(ctx, invocation.InvocationID) |
| if agent.CredentialName != "" { | ||
| pterm.Println(fmt.Sprintf(" Credential: %s", agent.CredentialName)) | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Returning nil on failure states like expired/canceled/failed means callers won't know an error occurred. For CLI usage this might be intentional, but consider returning an error so the exit code reflects the failure (e.g., return fmt.Errorf("invocation failed: %s", state.ErrorMessage)).
- Update SDK to v0.25.0 with new import path github.com/kernel/kernel-go-sdk - Add agents auth list command with filtering - Add agents auth invocation get/submit commands - Add full credentials CLI (create, get, list, update, delete, totp-code) - Add interactive mode (-i) for agent auth create with profile/credential selectors Co-Authored-By: Claude Opus 4.5 <[email protected]>
| case kernel.AgentAuthInvocationResponseStatusExpired: | ||
| pterm.Println() | ||
| pterm.Error.Println("Invocation expired") | ||
| return nil | ||
|
|
||
| case kernel.AgentAuthInvocationResponseStatusCanceled: | ||
| pterm.Println() | ||
| pterm.Error.Println("Invocation was canceled") | ||
| return nil | ||
|
|
||
| case kernel.AgentAuthInvocationResponseStatusFailed: | ||
| pterm.Println() | ||
| pterm.Error.Println("Invocation failed") | ||
| if state.ErrorMessage != "" { | ||
| pterm.Error.Printf(" Error: %s\n", state.ErrorMessage) | ||
| } | ||
| return nil | ||
| } | ||
|
|
||
| time.Sleep(pollInterval) | ||
| } | ||
|
|
||
| pterm.Error.Println("Polling timed out after 5 minutes") | ||
| return nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Returning nil here still exits 0 even on expired/canceled/failed/timeout. If callers/scripts rely on exit status, returning an error makes this easier to handle.
| case kernel.AgentAuthInvocationResponseStatusExpired: | |
| pterm.Println() | |
| pterm.Error.Println("Invocation expired") | |
| return nil | |
| case kernel.AgentAuthInvocationResponseStatusCanceled: | |
| pterm.Println() | |
| pterm.Error.Println("Invocation was canceled") | |
| return nil | |
| case kernel.AgentAuthInvocationResponseStatusFailed: | |
| pterm.Println() | |
| pterm.Error.Println("Invocation failed") | |
| if state.ErrorMessage != "" { | |
| pterm.Error.Printf(" Error: %s\n", state.ErrorMessage) | |
| } | |
| return nil | |
| } | |
| time.Sleep(pollInterval) | |
| } | |
| pterm.Error.Println("Polling timed out after 5 minutes") | |
| return nil | |
| case kernel.AgentAuthInvocationResponseStatusExpired: | |
| pterm.Println() | |
| pterm.Error.Println("Invocation expired") | |
| return fmt.Errorf("invocation expired") | |
| case kernel.AgentAuthInvocationResponseStatusCanceled: | |
| pterm.Println() | |
| pterm.Error.Println("Invocation was canceled") | |
| return fmt.Errorf("invocation was canceled") | |
| case kernel.AgentAuthInvocationResponseStatusFailed: | |
| pterm.Println() | |
| pterm.Error.Println("Invocation failed") | |
| if state.ErrorMessage != "" { | |
| pterm.Error.Printf(" Error: %s\n", state.ErrorMessage) | |
| return fmt.Errorf("invocation failed: %s", state.ErrorMessage) | |
| } | |
| return fmt.Errorf("invocation failed") | |
| } | |
| time.Sleep(pollInterval) | |
| } | |
| pterm.Error.Println("Polling timed out after 5 minutes") | |
| return fmt.Errorf("polling timed out after %s", maxWaitTime) |
| if cred.TotpCode != "" { | ||
| rows = append(rows, []string{"TOTP Code", cred.TotpCode}) | ||
| rows = append(rows, []string{"TOTP Expires", cred.TotpCodeExpiresAt.Format(time.RFC3339)}) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor footgun: printing a fresh TOTP code during create (and similarly in update) is easy to leak via terminal scrollback/log capture. I’d avoid printing codes except via the explicit totp-code command.
| if cred.TotpCode != "" { | |
| rows = append(rows, []string{"TOTP Code", cred.TotpCode}) | |
| rows = append(rows, []string{"TOTP Expires", cred.TotpCodeExpiresAt.Format(time.RFC3339)}) | |
| } | |
| // Avoid printing TOTP codes here; use `credentials totp-code` when needed. |
Shows how to invoke the auth agent after creation. Co-Authored-By: Claude Opus 4.5 <[email protected]>
Users can now run `kernel agents auth invoke -i` to select an auth agent from a list instead of providing the ID directly. Co-Authored-By: Claude Opus 4.5 <[email protected]>
| options := []string{} | ||
| agentMap := make(map[string]string) // display -> id | ||
| for _, agent := range page.Items { | ||
| display := fmt.Sprintf("%s - %s (%s)", agent.ID[:8], agent.Domain, agent.ProfileName) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ID slice panics if agent ID shorter than 8 chars
Medium Severity
The expression agent.ID[:8] will cause a panic if agent.ID is shorter than 8 characters. While IDs are typically UUIDs (36 characters), this could panic if the API returns an empty string, a malformed ID, or if the ID format changes. The code iterates over page.Items and slices each ID without a length check.
The hosted URL was causing 404 errors. Now we fetch the live view URL from the first poll after creating the invocation and use that instead. Co-Authored-By: Claude Opus 4.5 <[email protected]>
Co-Authored-By: Claude Opus 4.5 <[email protected]>
Note
Introduces end-to-end agent authentication and credential management in the CLI, alongside a dependency migration to the new SDK module.
agents authcommands:create,invoke,get,delete,list, plus invocation subcommandsinvocation getandinvocation submit; supports hosted UI login (auto-opens browser), live polling, SSO/button/field submission, and interactive selection flowscredentialscommands:create,get,list,update,delete,totp-codefor storing login data and retrieving current TOTP codesagentsandcredentialscommand groupsgithub.com/onkernel/kernel-go-sdktogithub.com/kernel/kernel-go-sdkand bumps dependency tov0.25.0(updates acrosscmd/*,pkg/*,go.mod,go.sum)Written by Cursor Bugbot for commit dc09ad8. This will update automatically on new commits. Configure here.