-
Notifications
You must be signed in to change notification settings - Fork 10.1k
feat(auth): improve API key authentication flow #11760
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
Conversation
This commit introduces a series of improvements to the API key authentication process. These changes result in a more robust and user-friendly authentication experience when using a Gemini API key.
Summary of ChangesHello @galz10, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances the user experience for Gemini API key authentication within the CLI. It introduces a dedicated interactive dialog for API key input and ensures secure storage of these keys in the system's keychain. This change centralizes API key management, reduces friction for repeated use, and refactors underlying authentication mechanisms for improved maintainability and robustness. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
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.
Code Review
This PR introduces a new, improved authentication flow for Gemini API keys, featuring a dedicated input dialog and secure keychain storage. The refactoring enhances maintainability and user experience. However, I've identified a few high-severity issues that should be addressed. The API key input is not masked, which is a security concern. There's an inconsistency in API key source precedence between different parts of the code, which could lead to unexpected behavior. Finally, there's no validation for empty API key submissions, potentially leaving the application in a broken state. Fixing these issues will make the new authentication flow more robust and secure.
| async (apiKey: string) => { | ||
| try { | ||
| await ApiKeyCredentialStorage.saveApiKey(apiKey); | ||
| await reloadApiKey(); | ||
| await config.refreshAuth(AuthType.USE_GEMINI); | ||
| setAuthState(AuthState.Authenticated); | ||
| } catch (e) { | ||
| onAuthError( | ||
| `Failed to save API key: ${e instanceof Error ? e.message : String(e)}`, | ||
| ); | ||
| } | ||
| }, |
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 handleApiKeySubmit function does not validate if the submitted API key is empty or contains only whitespace. Submitting an empty key will cause ApiKeyCredentialStorage.saveApiKey to delete any existing key, and the subsequent authentication will likely fail silently or with a confusing error, leaving the application in a broken state where it appears authenticated but has no valid key. You should add a check at the beginning of handleApiKeySubmit to ensure the key is not empty and use onAuthError to display a message to the user if it is.
async (apiKey: string) => {
if (!apiKey.trim()) {
onAuthError('API key cannot be empty.');
return;
}
try {
await ApiKeyCredentialStorage.saveApiKey(apiKey);
await reloadApiKey();
await config.refreshAuth(AuthType.USE_GEMINI);
setAuthState(AuthState.Authenticated);
} catch (e) {
onAuthError(
`Failed to save API key: ${e instanceof Error ? e.message : String(e)}`,
);
}
},
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.
I can do this, but since we are using keychain, i think it makes sense that if the api key is an empty string, then we clear the api key, i'll add a check to see if the user just enters a bunch of white spaces then we should raise this error.
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.
agree it is worth it. it is odd I can submit the dialog when the apikey is empty. i should have to press escape and I should get an error message explaining why submit was blocked.
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
|
Size Change: +9.93 kB (+0.05%) Total Size: 20.3 MB
ℹ️ View Unchanged
|
| try { | ||
| await this.storage.deleteCredentials(DEFAULT_API_KEY_ENTRY); | ||
| } catch (error: unknown) { | ||
| console.error('Failed to clear API key from storage:', error); |
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.
no need to log and throw
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.
i feel like logging to the debugLogger might be helpful
| } | ||
|
|
||
| // Normal character input | ||
| if (key.sequence && !key.ctrl && !key.meta) { |
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.
we are letting a lot of unsafe chars in. examples: tabs, up arrow, down arrow. UI does really weird things due to this if you press up or down arrows.
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.
Nothing happens if you press up, down, tab
jacob314
left a comment
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.
other issue noticed manually testing:
ctrl-c now doesn't seem to work in the api key dialog or the auth dialog. odd that changed as they do work in that dialog on the public build.
This commit refactors the TextInput component to be a controlled component that uses the useTextBuffer hook to manage its state. This change simplifies the TextInput component and makes it more reusable. The ApiAuthDialog has been updated to use the new TextInput component. Additionally, the AP key resolution logic has been updated to prioritize the stored API key over the GEMINI_API_KEY environment variable.
| useTextBuffer({ | ||
| viewport, | ||
| isValidPath: () => false, | ||
| inputFilter: (text) => text.replace(/[^0-9]/g, ''), |
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.
nit: it might make sense to also apply the inputFilter to the initial value passed in but not sure that is a good idea.
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.
so inputFilter is optional, we can apply it but it might be overkill, i think the idea is that whatever is in intitialValue will be valid
jacob314
left a comment
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.
Everything works well now when I manually test it. Did one final round of review comments then approved.
jacob314
left a comment
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.
…/google-gemini/gemini-cli into galzahavi/add/interactive-prompt
TLDR
This PR improves the authentication flow for Gemini API keys. It introduces a new dialog for API key input, securely stores the key, and refactors the related code for better maintainability.
Dive Deeper
The main changes in this PR are:
ApiAuthDialog: A new React componentApiAuthDialogis created to prompt the user for their Gemini API key. This provides a better user experience than relying on environment variables.ApiKeyCredentialStorage: A new classApiKeyCredentialStorageis added to securely store the API key in the system's keychain. This avoids having to re-enter the key on every run.useAuthhook: TheuseAuthhook is refactored to handle the new API key input flow. The logic for loading the API key is centralized in thereloadApiKeyfunction.TextInputcomponent: TheTextInputcomponent is refactored to be a fully controlled component, which simplifies its implementation and makes it more reusable.ApiKeyCredentialStorage.Reviewer Test Plan
Run the Gemini CLI without any authentication configured.
Select "Gemini API Key" as the authentication method.
You should be prompted to enter your API key in a new dialog.
Enter a valid API key. The CLI should authenticate successfully.
To test the clearing of the key, you can manually delete the entry from your keychain (service name:
gemini-cli-api-key) and rerun the CLI. You should be prompted for the key again.Unset GEMINI_API_KEY environent variable
Run the Gemini CLI with "Gemini API Key" authentication configured.
You should be prompted to enter your API key in a new dialog.
Enter a valid API key. The CLI should authenticate successfully.
Testing Matrix
Linked issues / bugs
No linked issues