feat: add OAuth2 authentication with PKCE support#84
Conversation
Implement OAuth2 Authorization Code Grant flow with PKCE for browser-based authentication as an alternative to API keys. New features: - OAuth2 PKCE flow with secure code verifier/challenge generation - Local callback server for receiving authorization codes - Secure token storage at ~/.datadog/oauth_tokens.json (0600 permissions) - Automatic token refresh with request deduplication - CLI commands: auth login, logout, status, refresh Changes: - Add src/lib/auth/ module with oauth-client, token-storage, callback-server, token-refresher, and commands - Update config.ts to support both API key and OAuth authentication - Update client.ts with OAuthHttpLibrary for Bearer token auth - Add OAuth error types to error-handler.ts - Add auth command routing to index.ts - Add .claude/ to .gitignore Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
✅ Library Vulnerabilities 🎉 All green!📚 No new vulnerable libraries detected 🔗 Commit SHA: 3febc6f | Docs | Datadog PR Page | Was this helpful? Give us feedback! |
…scopes Updated DEFAULT_OAUTH_SCOPES to include all Datadog OAuth2 scopes that map to current plugin tools. This enables OAuth authentication to work with the full range of plugin functionality that has available scopes. Scopes added: - Monitors: monitors_read, monitors_write, monitors_downtime - APM/Traces: apm_read - SLOs: slos_read, slos_write, slos_corrections - Incidents: incident_read, incident_write - Synthetics: full read/write scopes including global variables and private locations - Security: monitoring signals, rules, findings, suppressions, filters - RUM: apps and retention filter scopes (rum_read/metrics not yet available) - Infrastructure: hosts_read - Users: user_access_read, user_self_profile_read - Cases: cases_read, cases_write - Events: events_read - Metrics: metrics_read, timeseries_query (metrics_write not yet available) - Usage: usage_read Note: Some tools cannot use OAuth yet due to missing scopes: - Logs (logs_read not available) - Metrics submit (metrics_write not available) - RUM events search (rum_read not available) - Key Management (api_keys_*, app_keys_* not available) - Fleet Automation (fleet_* not available) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement secure token storage using @napi-rs/keyring to store OAuth tokens in the operating system's native secure storage: - macOS: Keychain - Windows: Credential Manager - Linux: Secret Service (libsecret) This provides hardware-backed encryption where available and eliminates the security risk of storing tokens as plaintext JSON files. Key changes: - Add SecureTokenStorage class using @napi-rs/keyring - Add TokenStorageFactory with auto-detection and fallback logic - Add token migration from legacy file storage to keychain - Rename TokenStorage to FileTokenStorage (with backward-compat alias) - Add ITokenStorage interface for storage abstraction - Update commands.ts to show storage backend in status - Add DD_TOKEN_STORAGE env var for explicit backend selection Selection priority: 1. DD_TOKEN_STORAGE=file → use file storage 2. DD_TOKEN_STORAGE=keychain → use keychain (fail if unavailable) 3. Auto-detect: try keychain, fall back to file with warning Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
One pretty clear downside of this approach is the lack of API key == no obvious way to use the send metrics or events functionality. Need to think about this a bit more |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 42ea88e4b2
ℹ️ 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".
The auth module is a CLI tool that requires console output for user interaction (login prompts, status messages, error feedback). This silences the DD Static Analyzer warnings for intentional console usage. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement RFC 7591 Dynamic Client Registration to replace hardcoded OAuth client ID with per-installation dynamically registered clients. Changes: - Add dcr-types.ts with DCR interfaces and constants - Add dcr-client.ts with registerClient() and getOrRegisterClient() - Add client-credentials-storage.ts with keychain and file backends - Update oauth-client.ts to require clientId parameter (no defaults) - Update commands.ts to integrate DCR into login flow - Update token-refresher.ts to use stored clientId for refresh - Update callback-server.ts to prefer DCR-registered ports - Remove hardcoded DATADOG_CLI_CLIENT_ID constant - Fix RUM scope typos (rum_retention_filters_read/write) - Add unit tests for all new modules Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix race condition in CallbackServer between start() and waitForCallback() by buffering callback results and using polling instead of duplicate handlers - Add explicit comment for empty callback in test - Fix test expectation for DCR redirect URIs (127.0.0.1 not localhost) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
@codex review |
|
To use Codex here, create a Codex account and connect to github. |
- Add OAuth as the primary authentication method with full command reference - Document auth login, logout, status, and refresh commands - Move API/APP key configuration to fallback option for CI/CD environments - Add OAuth troubleshooting sections for expired tokens and browser issues - Update security best practices to prioritize OAuth authentication - Highlight secure OS keychain storage in Security First section Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 456f1ea250
ℹ️ 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".
Previously, findAvailablePort() would fall back to scanning ports 8000-9000 if the preferred ports (8000, 8080, 8888, 9000) were all in use. However, only these four ports are registered with DCR, so using any other port would result in an invalid_redirect_uri error. Now the function only tries DCR-registered ports and throws a clear error message if none are available, instead of silently failing with a confusing OAuth error later. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Summary
Adds OAuth2 authentication capability to the Datadog API Claude Plugin, enabling secure user authentication via browser-based login flow with PKCE protection. This is an alternative to API key authentication - users can now choose to authenticate either way.
Note: This PR adds OAuth2 authentication infrastructure only. No changes were made to the code generation functionality or how the plugin generates Datadog API client code.
What Users Can Do
With OAuth2 authentication, users can:
auth loginopens Datadog authorization pageauth statusshows current token stateauth refreshmanually refreshes access tokenauth logoutclears stored tokensOAuth2 Features
New Dependency
@napi-rs/keyring(^1.2.0): Native OS keychain integration for secure token storage (macOS Keychain, Windows Credential Manager, Linux Secret Service)Supported OAuth Scopes
The OAuth flow requests access to these Datadog capabilities:
dashboards_read,dashboards_writemonitors_read,monitors_write,monitors_downtimeapm_readslos_read,slos_write,slos_correctionsincident_read,incident_writesynthetics_read,synthetics_write,synthetics_global_variable_*,synthetics_private_location_*security_monitoring_signals_read,security_monitoring_rules_read,security_monitoring_findings_read,security_monitoring_suppressions_read,security_monitoring_filters_readrum_apps_read,rum_apps_write,rum_retention_filters_read,rum_retention_filters_writehosts_readuser_access_read,user_self_profile_readcases_read,cases_writeevents_readlogs_read_data,logs_read_index_datametrics_read,timeseries_queryusage_readSecurity Model
client_idvia Dynamic Client RegistrationNew Files
src/lib/auth/dcr-types.tssrc/lib/auth/dcr-client.tssrc/lib/auth/client-credentials-storage.tssrc/lib/auth/oauth-client.tssrc/lib/auth/token-refresher.tssrc/lib/auth/callback-server.tssrc/lib/auth/token-storage.tssrc/lib/auth/token-storage-factory.tssrc/lib/auth/commands.tsTest Plan
Response by Claude 🤖