From 43e1efd4d671273516b47659b2f3232a722bb591 Mon Sep 17 00:00:00 2001 From: jansen-w Date: Wed, 20 May 2026 14:07:46 -0400 Subject: [PATCH 1/2] Add Observability Pipelines OAuth scopes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently `pup obs-pipelines list` (and every other OP subcommand) returns 401 Unauthorized when called with OAuth credentials, because pup's default scope set never requests any `observability_pipelines_*` scope. The CLI side has `pup obs-pipelines …` wired up, and `agents/observability-pipelines.md` already documents that the routes require `observability_pipelines_read`, `observability_pipelines_deploy`, and `observability_pipelines_delete` — this PR closes that gap by adding those scopes to the default consent set. - `observability_pipelines_read` added to both `default_scopes()` and `read_only_scopes()`. - `observability_pipelines_deploy` and `observability_pipelines_delete` added to `default_scopes()` only (write/destructive). - Updated `test_default_scopes()` count from 85 to 88 and added containment assertions for all three new scopes. --- src/auth/types.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/auth/types.rs b/src/auth/types.rs index c3d9067..f0cc7fa 100644 --- a/src/auth/types.rs +++ b/src/auth/types.rs @@ -78,6 +78,7 @@ pub fn read_only_scopes() -> Vec<&'static str> { "metrics_read", "monitors_read", "notebooks_read", + "observability_pipelines_read", "oci_configuration_read", "on_call_read", "reference_tables_read", @@ -179,6 +180,10 @@ pub fn default_scopes() -> Vec<&'static str> { // Notebooks "notebooks_read", "notebooks_write", + // Observability Pipelines + "observability_pipelines_read", + "observability_pipelines_deploy", + "observability_pipelines_delete", // OCI "oci_configuration_edit", "oci_configuration_read", @@ -271,7 +276,7 @@ mod tests { #[test] fn test_default_scopes() { let scopes = default_scopes(); - assert_eq!(scopes.len(), 85); + assert_eq!(scopes.len(), 88); assert!(scopes.contains(&"dashboards_read")); assert!(scopes.contains(&"monitors_read")); assert!(scopes.contains(&"logs_read_data")); @@ -290,6 +295,10 @@ mod tests { assert!(scopes.contains(&"on_call_write")); assert!(scopes.contains(&"aws_configuration_read")); assert!(scopes.contains(&"gcp_configuration_read")); + // Observability Pipelines + assert!(scopes.contains(&"observability_pipelines_read")); + assert!(scopes.contains(&"observability_pipelines_deploy")); + assert!(scopes.contains(&"observability_pipelines_delete")); } #[test] From 4fd71f3bedfc5e2693760309acde63666b75681e Mon Sep 17 00:00:00 2001 From: jansen-w Date: Wed, 20 May 2026 15:35:53 -0400 Subject: [PATCH 2/2] Switch obs-pipelines commands to OAuth-capable API client The `make_api!` macro sends the OAuth bearer token when one is available and falls back to API-key headers otherwise. Previously the OP commands used `make_api_no_auth!`, which suppressed the bearer header outright because the OP routes did not accept `ValidOAuthAccessToken` on the server side. Server-side support for OAuth on the OP public routes is in flight (DataDog/dd-source#426541 covers the Rapid-side authn list on obs-pipelines-crud; DataDog/dd-go#238110 covers the Route Manager allowlist on rc-api-proxy across staging/prod/gov). Once those land and pup's OAuth client gets the OP scopes added, this change unblocks `pup obs-pipelines` via OAuth without further client work. Pattern copied from the prior attempt in PR #342, adapted to the current `make_api!` macro (which subsumed the older `make_bearer_client` helper used in that PR). --- src/commands/obs_pipelines.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/commands/obs_pipelines.rs b/src/commands/obs_pipelines.rs index f6765de..05bc3bf 100644 --- a/src/commands/obs_pipelines.rs +++ b/src/commands/obs_pipelines.rs @@ -9,8 +9,7 @@ use crate::formatter; use crate::util; fn make_api(cfg: &Config) -> ObservabilityPipelinesAPI { - // Observability Pipelines does not support OAuth — API key auth only. - crate::make_api_no_auth!(ObservabilityPipelinesAPI, cfg) + crate::make_api!(ObservabilityPipelinesAPI, cfg) } pub async fn list(cfg: &Config, limit: i64) -> Result<()> {