Skip to content

Re-add APM service remapping CRUD commands#498

Merged
platinummonkey merged 2 commits into
DataDog:mainfrom
srosenthal-dd:stephen.rosenthal/add-apm-service-renaming-write
May 12, 2026
Merged

Re-add APM service remapping CRUD commands#498
platinummonkey merged 2 commits into
DataDog:mainfrom
srosenthal-dd:stephen.rosenthal/add-apm-service-renaming-write

Conversation

@srosenthal-dd
Copy link
Copy Markdown
Member

@srosenthal-dd srosenthal-dd commented May 12, 2026

Context

Resurrects #439, which was reverted in #454 because pup auth login failed with invalid_scope once the new scope was requested. The server-side DCR client allowlist is now in place, so the original failure mode is resolved.

Requested by @rachelyangdog

Summary

Restores the four files removed by the revert, with one updated test assertion to match current main:

  • pup apm service-remapping {list,create,get,update,delete} (new commands wired in src/main.rs, implementation in src/commands/apm.rs)
  • apm_service_renaming_write added to default_scopes() in src/auth/types.rs
  • raw_put helper added to src/client.rs to support the update (PUT) endpoint
  • test_default_scopes length assertion 84 -> 85

No exclusion-list changes: the original PR briefly added then removed three /api/v2/service-naming-rules entries from OAUTH_EXCLUDED_ENDPOINTS; net effect was zero. Current main has no such entries, so OAuth is used for these routes by default -- which is what we want.

Test plan

  • cargo build, cargo fmt --check, cargo clippy --all-targets -- -D warnings clean
  • cargo test --bin pup auth::types (9 passed)
  • cargo test --bin pup -- --test-threads=1 commands::apm (19 passed, including 11 new service_remapping_* tests)
  • End-to-end against both datad0g.com (staging) and datadoghq.com (prod): login issues a token containing apm_service_renaming_write, service-remapping list returns real rules, and service-remapping delete <bogus-uuid> 1 reaches the service (404 in staging, 403 RBAC in prod) -- proving the scope is honored end-to-end. Transcripts in a comment below.

Resurrects DataDog#439 (reverted in DataDog#454). The original revert was because pup's
`default_scopes()` requested `apm_service_renaming_write` before that
scope was on pup's server-side DCR client allowlist, breaking every
`pup auth login` with `invalid_scope`. The allowlist is now in place,
verified end-to-end against app.datadoghq.com with this build:

- `pup auth login` succeeds with `apm_service_renaming_write` in the token
- `pup apm service-remapping list` returns the rules
- `pup apm service-remapping delete <bogus-uuid> 1` returns 404 (scope
  passed; rule not found), confirming the write scope is honored

Test-count assertion bumped 84 -> 85 to match current main.

Adds back:
- `pup apm service-remapping {list,create,get,update,delete}` commands
- `apm_service_renaming_write` in `default_scopes()`
- `raw_put` helper in `client.rs`
@srosenthal-dd
Copy link
Copy Markdown
Member Author

srosenthal-dd commented May 12, 2026

End-to-end transcripts proving the scope is wired through (from Claude Code).

Staging (datad0g.com)

$ pup auth login
🔑 Requesting 85 scope(s) (use --scopes to customize)
... browser flow ...
✅ Login successful!

$ pup auth status | jq '.scopes | index("apm_service_renaming_write")'
2   # present

$ pup apm service-remapping list
{"data":[...49 rules...]}

$ pup apm service-remapping delete 00000000-0000-0000-0000-000000000000 1
Error: DELETE https://api.datad0g.com/api/v2/service-naming-rules/00000000-0000-0000-0000-000000000000/1
       failed (HTTP 404): {"errors":[{"status":"404","title":"Not Found",
       "detail":"Rule with ID 00000000-0000-0000-0000-000000000000 not found"}]}

404 = scope passed Smart Edge, rule lookup miss.

Prod (datadoghq.com)

$ pup auth status | jq '.scopes | index("apm_service_renaming_write")'
2   # present

$ pup apm service-remapping list
{"data":[...22 rules...]}

$ pup apm service-remapping delete 00000000-0000-0000-0000-000000000000 1
Error: DELETE https://api.datadoghq.com/api/v2/service-naming-rules/00000000-0000-0000-0000-000000000000/1
       failed (HTTP 403): {"errors":["Forbidden","Failed permission authorization checks"]}

403 with "Failed permission authorization checks" is a downstream RBAC check (the test account lacks the apm_service_renaming_write user permission), not a scope rejection -- the request had to reach the service for that check to run. Different terminal failure (404 vs 403) in the two environments, same conclusion: the OAuth scope is honored end-to-end.

@srosenthal-dd srosenthal-dd marked this pull request as ready for review May 12, 2026 19:46
@srosenthal-dd srosenthal-dd requested a review from a team as a code owner May 12, 2026 19:46
Restored from DataDog#439 verbatim, but main has since moved every other raw_* helper
onto parse_response_json (deep-stack JSON parsing via serde_stacker to bypass
serde_json's 128-level recursion cap). Match that pattern so service remapping
update doesn't re-introduce the pre-hardening failure mode for deeply nested
PUT responses.
@platinummonkey platinummonkey merged commit f227303 into DataDog:main May 12, 2026
6 checks passed
@srosenthal-dd srosenthal-dd deleted the stephen.rosenthal/add-apm-service-renaming-write branch May 13, 2026 00:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants