mcpField
D
dd-account-setup

dd-account-setup

github.com/datadog-labs云与 DevOps18044 次安装6 天前更新
代码仓库

关于 dd-account-setup

dd-account-setup 是引导用户连接或创建 Datadog 账户的技能,适用于准备 API key、application key 和站点区域的场景。它检测已有凭据,支持 OAuth 登录或创建账户,并通过 Datadog API 验证密钥。

主要功能

  1. 01检测环境变量与 .env 凭据
  2. 02确认 Datadog 站点区域
  3. 03通过 OAuth 登录或创建账户
  4. 04生成并保存 API key
  5. 05调用 API 验证凭据

适用场景

  1. 01为 Datadog 初次配置凭据
  2. 02验证已有 API key 与站点
  3. 03为后续监控配置准备账户

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/datadog-labs/agent-skills --skill dd-account-setup

安装后在 Claude Code 中输入/dd-account-setup确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
authenticate.md
conventions.md
get-api-key.md
regions.md
troubleshooting.md

详细介绍

创建 / 连接 Datadog 账户

此技能会帮助用户达到已知的可用状态:有效的 API 密钥 + 应用密钥,位于正确的区域,并通过 Datadog API 验证。 这是设置 / 插桩技能所依赖的“第 0 步”——先运行此技能,然后再交接。

这是一个独立的引导流程:检测现有内容;如果没有找到可用的内容,则通过 OAuth(浏览器、PKCE + state)登录,或创建新账户(在终端内操作,并将生成的密码保存到 .env),然后将该会话转换为 API 密钥。所有操作都通过简短的内联 bash + curl 命令完成(OAuth 还会用到 openssl)——没有捆绑脚本,也不需要 node;支持跨平台(macOS、Linux、通过 WSL/Git Bash 使用 Windows)。

此 SKILL.md 是整个流程的主干——它内含简短步骤,并在需要时引导至 references/,获取每一步的详细操作。只有在到达提及相应参考文件的步骤时才阅读它。

流程一览

headless requested?  ──yes──▶  Step H: env keys only (OAuth needs a browser), validate, done
   │no (default — interactive)
   ▼
Step 1  Detect existing credentials (env)
   │
   ▼
Step 2  Determine region / site  (DD_SITE → validate; else ask → user picks, default US1)
   │
   ▼
Step 3  Authenticate  — ask first (even if env keys were detected)   → references/authenticate.md
   │        └─ ASK: how to connect? ↴
   │            ├─ A. Use the detected env key (only if one exists) → validate → Step 5
   │            ├─ B. Sign in (I have an account) → OAuth (browser, PKCE + state) ──▶ Bearer token
   │            └─ C. Create a new account → Path C: auto in-terminal signup, generated password ──▶ then OAuth
   ▼
Step 4  Turn the OAuth session into an API key   → references/get-api-key.md
   │        (identity + region via /current_user; OAuth→retrieve most-recent key, app-key→create → write straight to .env; else guide to UI key page)
   ▼
Step 5  Load creds from .env, validate, hand off

黄金法则:绝不猜测或伪造 API 密钥、应用密钥、令牌或站点。 读取环境中的内容并进行验证;如果不存在,就进行身份验证——不要凭假设继续操作。

显示与措辞约定——在步骤 1 前阅读一次

每个步骤都遵循相同的规则,与用户交流并呈现进度:简洁状态行的呈现约定、使用宿主的原生选择器提问(绝不让用户输入字母),以及带有标记规范的实时进度清单。这些规则位于 references/conventions.md 中——在步骤 1 前阅读,并在整个流程中遵循。下方每个步骤末尾都有一个 ↳ Checklist: 提示,说明需要更新哪些项目。


步骤 0 — 预检(就绪状态面板)

先运行一次,让用户在任何操作开始前看到完整流程——有哪些工具可用、已检测到什么,以及流程将执行什么操作(包括会打开一次浏览器)。此步骤不会写入任何内容,也不会泄露秘密信息。每次调用都会从步骤 1 开始运行完整流程——不会恢复或跳过步骤,也不会沿用之前运行的结果。

DDLOG="${TMPDIR:-/tmp}/dd-onboard-$(id -u).log"; : >"$DDLOG"   # fresh log for this run
mark(){ command -v "$1" >/dev/null 2>&1 && echo "✓" || echo "$2"; }
# python3 gates the auto browser-callback; fall back to python only if it's a real py3.
have_py3(){ command -v python3 >/dev/null 2>&1 && return 0; command -v python >/dev/null 2>&1 && python -c 'import sys;exit(0 if sys.version_info[0]==3 else 1)' 2>/dev/null; }
py3msg(){ have_py3 && echo '✓ (auto browser-callback)' || echo '⊘ (will paste the redirect URL)'; }
echo   "Datadog account setup — preflight"
echo   "  deps (required):  bash ✓   curl $(mark curl ✗)   openssl $(mark openssl ✗)"
echo   "  deps (optional):  python3 $(py3msg)   browser-open $( { command -v open >/dev/null 2>&1 || command -v xdg-open >/dev/null 2>&1; } && echo ✓ || echo '⊘ (open URL manually)')"
# Canonical DD_* loader — this same block is repeated verbatim in later steps because each ```bash runs a fresh shell (not drift).
# Load DD_* with precedence: shell env > .env.local > .env. A real env var is never overwritten; surrounding quotes are stripped. *_SRC records where each came from (unset ⇒ from the shell env).
for f in .env.local .env; do [ -f "$f" ] || continue; for k in DD_SITE DD_API_KEY DD_APP_KEY; do eval "[ -n \"\${$k:-}\" ]" && continue; v=$(grep -E "^$k=" "$f" | head -1 | cut -d= -f2- | sed 's/^["'\'']//;s/["'\'']$//'); [ -n "$v" ] && { export "$k=$v"; eval "${k}_SRC=$f"; }; done; done
echo   "  detected creds:   DD_SITE=${DD_SITE:-<unset>}${DD_SITE_SRC:+ [$DD_SITE_SRC]}   DD_API_KEY=$([ -n "$DD_API_KEY" ] && echo "set …${DD_API_KEY: -4}${DD_API_KEY_SRC:+ [$DD_API_KEY_SRC]}" || echo '<unset>')   DD_APP_KEY=$([ -n "$DD_APP_KEY" ] && echo "set${DD_APP_KEY_SRC:+ [$DD_APP_KEY_SRC]}" || echo '<unset>')"
echo   "  what happens:     confirm region → authenticate (opens your browser once) → get an API key → write it to .env → validate. ~2 min, one browser approval."
[ "$(mark curl ✗)" = ✗ ] || [ "$(mark openssl ✗)" = ✗ ] && echo "  ✗ missing a required dep above — install it before continuing."

原样向用户展示状态面板(它已经简洁明了)。如果缺少必需的依赖项,则停止并说明情况。然后勾选清单中的步骤 1 并继续——始终进入步骤 1;绝不能跳到后续步骤。

↳ 清单: 先展示状态面板,再展示清单;将1. 检测凭据标记为 ◔。


步骤 H — 无头 / 非交互模式(无浏览器、无提示)

首先判断是否属于此模式,因为没有人工参与就无法使用浏览器或注册流程。根据技能的调用方式判断无头模式,而不是根据环境判断——触发条件是用户的请求本身:用户明确要求在没有浏览器或交互式提示的情况下运行(例如“以非交互方式设置 Datadog”“我在 CI 环境中,没有浏览器”)。

不要仅因为缺少 TTY 就判断为无头模式——普通终端运行始终使用交互式流程。只有明确提出的请求才会关闭交互。

判断用户要求无头模式后,再运行下方代码块。OAuth 无法打开浏览器,注册提示也无人作答,因此达到有效状态的唯一方式是使用已提供的密钥。要求设置 DD_API_KEY、DD_APP_KEY 和 DD_SITE,否则立即失败:

# Run this block ONLY when you inferred a non-interactive request. It enforces the one thing
# headless needs — keys already present — and fails fast when any are missing.
# Load DD_* (env > .env.local > .env), same precedence as Step 1 — CI keys often live in .env, not exported.
for f in .env.local .env; do [ -f "$f" ] || continue; for k in DD_SITE DD_API_KEY DD_APP_KEY; do eval "[ -n \"\${$k:-}\" ]" && continue; v=$(grep -E "^$k=" "$f" | head -1 | cut -d= -f2- | sed 's/^["'\'']//;s/["'\'']$//'); [ -n "$v" ] && export "$k=$v"; done; done
missing=""
[ -z "$DD_API_KEY" ] && missing="$missing DD_API_KEY"
[ -z "$DD_APP_KEY" ] && missing="$missing DD_APP_KEY"
[ -z "$DD_SITE" ]    && missing="$missing DD_SITE"
[ -n "$missing" ] && { echo "Non-interactive mode requires:$missing — set them and re-run. Sign-in and trial signup need a browser."; exit 1; }

如果这三项都已设置,则交接至步骤 5,通过 /api/v1/validate 验证密钥(支持使用 DD-API-KEY 请求头)。注意:/api/v1/validate 只检查 DD_API_KEY——DD_APP_KEY 虽为必需项,但不会在此单独验证;错误或过期的应用密钥会在首次调用需要应用密钥的接口时显现。无头模式下没有 OAuth 或注册的备用路径——这两种方式都需要浏览器——因此应使用上述消息报错,并确保日志便于采取后续操作。

↳ 清单(无头模式): 仅有两项——验证通过后勾选两项,并跳转至步骤 5。


步骤 1 — 检测现有凭据

读取环境变量以及项目的 .env / .env.local 文件。不要向用户完整显示这些值;请对其进行掩码处理。

# Load DD_* with precedence: shell env > .env.local > .env (real env var wins; quotes stripped). *_SRC = file it came from (unset ⇒ shell env).
for f in .env.local .env; do [ -f "$f" ] || continue; for k in DD_SITE DD_API_KEY DD_APP_KEY; do eval "[ -n \"\${$k:-}\" ]" && continue; v=$(grep -E "^$k=" "$f" | head -1 | cut -d= -f2- | sed 's/^["'\'']//;s/["'\'']$//'); [ -n "$v" ] && { export "$k=$v"; eval "${k}_SRC=$f"; }; done; done
echo "DD_SITE   = ${DD_SITE:-<unset>}${DD_SITE_SRC:+ (from $DD_SITE_SRC)}"
echo "DD_API_KEY= $( [ -n "$DD_API_KEY" ] && echo "set (…${DD_API_KEY: -4})${DD_API_KEY_SRC:+ (from $DD_API_KEY_SRC)}" || echo "<unset>" )"
echo "DD_APP_KEY= $( [ -n "$DD_APP_KEY" ] && echo "set (…${DD_APP_KEY: -4})${DD_APP_KEY_SRC:+ (from $DD_APP_KEY_SRC)}" || echo "<unset>" )"
  • 存在 DD_API_KEY(环境变量或.env/.env.local)→ 前往步骤 2(固定站点),然后执行步骤 3并询问(选项 A = 使用检测到的密钥,或选项 B/C 进行身份验证 / 创建其他账户)。检测到的密钥是用户在步骤 3 中确认后才可选择的选项,而不是默认静默使用的密钥——用户可能想使用其他组织或账户。
  • 任何位置都没有 DD_API_KEY → 用户目前没有可用的密钥。仍然执行步骤 2(确保注册页面落在正确的区域),然后前往步骤 3,询问用户如何连接。

只有应用密钥而没有 API 密钥是不够的;应视为“没有密钥”。由于 shell 不会在代码块之间持久保留,因此每个后续使用 $DD_API_KEY 的代码块都会在开头重新运行同一个加载器——这就是它会在路径 A、步骤 4 和步骤 5 中再次出现的原因。

↳ 清单: 现在发布列表 — 勾选 1. 检测凭据,将 2. 确认区域标记为 ◔。


步骤 2 — 确定区域 / 站点

站点会决定后续的所有 URL(注册、API 主机、密钥页面),因此请先固定站点,再进行验证。 区域表位于 references/regions.md。

  1. 如果已设置 DD_SITE(环境变量或 .env):根据 references/regions.md 中的允许站点列表验证它。如果它不在列表中,请停止并显示清晰的错误:

    DD_SITE="<value>" 不是已识别的 Datadog 站点。请从 references/regions.md 中选择一个区域,并相应地设置 DD_SITE。

  2. **如果未设置 DD_SITE:**请用户从 references/regions.md 中的表格选择一个区域——绝不要静默选定。不要尝试检测用户的位置(不要进行 IP 地理定位查询或其他第三方调用):正确的区域取决于其基础设施所在的位置,可能与用户所在地不同。如果用户没有偏好,默认使用 US1(datadoghq.com)。例如,告知用户:

    这个账户应位于哪个 Datadog 区域?请选择最靠近基础设施运行位置的区域(例如你的云区域)——将数据发送到很远的区域会增加延迟和出口流量成本,而且账户创建后无法更改区域。默认值:US1(弗吉尼亚州),datadoghq.com。

    使用主机原生选择器,并将 **US1(默认)**放在首位。如果选项数量受限,请按以下顺序尽可能多地列出 — US1、EU1、AP1、UK1 — 并让选择器中的自由文本“Other”选项涵盖其余区域。

    等待用户回复后再继续。用户简单地表示接受(“ok”“default”“sure”)即表示选择 US1。

API 主机统一为 https://api.${DD_SITE}。

↳ 清单: 用户确认区域后,勾选 2. 确认区域,将 3. 身份验证标记为 ◔。


第 3 步 — 身份验证

先询问如何连接 — 即使第 1 步检测到了环境凭据也要询问 — 然后执行用户选择的路径。在接触任何凭据之前,先展示“选项”:环境变量中的 DD_API_KEY 可能属于与用户预期不同的组织或账户,而区域无法揭示这一点,因此应让用户决定,而不是自行推断。(无头模式/第 H 步除外 — 没有 TTY 可供询问,只能使用环境变量中的密钥。)

完整详情 — “选项”的原生选择器措辞及全部三条路径 — 见 references/authenticate.md:

用户选择路径操作
使用我现有的凭据 (仅当第 1 步检测到密钥时才提供)A验证检测到的密钥(也会发现区域错误的密钥 → 返回第 2 步)。
登录 — 我已有账户B在浏览器中进行 OAuth(PKCE + state),将 Bearer 令牌写入 0600 文件。
创建新账户 (默认)C在终端中自动注册并生成密码 → 然后执行路径 B。

阅读 references/authenticate.md,通过宿主的原生选择器展示选项,然后执行匹配的路径。如果某条路径走不通,则重新提供选项(OAuth 未找到账户 → C;区域错误的密钥先让用户返回第 2 步)。

↳ 清单: 在实际拿到令牌或密钥之前,保持 3. 身份验证 ◔(参见 references/authenticate.md 中各路径的提示)。


第 4 步 — 将 OAuth 会话转换为 API 密钥

OAuth 令牌用于验证用户身份,但下游检测需要 DD_API_KEY。使用 Bearer 令牌确认身份,然后获取密钥 — OAuth 会话应检索组织最新的密钥(OAuth 令牌无法创建密钥);使用应用密钥进行身份验证时则应创建密钥;否则,引导用户前往 UI 密钥页面。

完整分支流程(身份检查、检索或创建、带 HTTP 状态码标记的代码块,以及 EMPTY_ORG / LIST_DENIED / SECRET_DENIED / CREATE_DENIED / TRANSPORT_ERROR 的结果表)见 references/get-api-key.md — 请遵循其中的说明。密钥会直接写入 .env,绝不会回显。

↳ 清单: 拿到经过验证的密钥后,勾选 4. 获取并验证 API 密钥,将 5 标记为 ◔。


第 5 步 — 确认并移交

密钥已在 .env 中。加载并验证密钥(每次调用都使用全新的 shell — 始终先通过解析的方式加载 .env,绝不要 source 它,以免精心构造的 .env 执行代码;绝不要将密钥明文写入命令):

DDLOG="${TMPDIR:-/tmp}/dd-onboard-$(id -u).log"; tf="${TMPDIR:-/tmp}/dd-oauth-$(id -u).token"
# Load DD_* (env > .env.local > .env) — parse, don't source, so a crafted .env can't execute. Covers a Path-A key that lives only in the shell env or .env.local.
for f in .env.local .env; do [ -f "$f" ] || continue; for k in DD_SITE DD_API_KEY DD_APP_KEY; do eval "[ -n \"\${$k:-}\" ]" && continue; v=$(grep -E "^$k=" "$f" | head -1 | cut -d= -f2- | sed 's/^["'\'']//;s/["'\'']$//'); [ -n "$v" ] && export "$k=$v"; done; done
vcode=$(curl -sg -o "$DDLOG" -w '%{http_code}' -H "DD-API-KEY: $DD_API_KEY" "https://api.${DD_SITE}/api/v1/validate")
# re-derive org/email for the card (fresh shell — Step 4 vars don't persist); only if a token is still around
who=""; [ -s "$tf" ] && who=$(curl -sg -H "Authorization: Bearer $(cat "$tf")" "https://api.${DD_SITE}/api/v2/current_user" 2>>"$DDLOG" | grep -oE '"email"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | cut -d'"' -f4)
cmk="${TMPDIR:-/tmp}/dd-signup-$(id -u).created"; spw=""   # marker exists only if THIS run created the account (Path C, C3) — no stale password from an earlier run
[ -f "$cmk" ] && spw=$(grep -E '^DD_SIGNUP_PASSWORD=' .env 2>/dev/null | tail -1 | cut -d= -f2-)   # newest .env entry = the password this run generated (C2 appends to .env)
# consistent 🔑 credential card — the one place credential state is summarized; secret shown only as last4
echo "🔑 Datadog credential"
[ -n "$who" ] && echo "   org:     $who"
echo "   region:  ${DD_SITE}"
echo "   api key: …${DD_API_KEY: -4}  (in .env — never printed in full)"
[ -n "$spw" ] && echo "   password: in .env as DD_SIGNUP_PASSWORD (ends …${spw: -4}) — you need it to sign in to Datadog"
echo "   status:  $([ "$vcode" = 200 ] && echo '✓ validated (HTTP 200)' || echo "✗ validate HTTP $vcode — see: tail -n 30 \"$DDLOG\"")"
  • 上方的卡片是规范摘要 — 不要同时倾倒原始验证响应。若返回非 200 状态码,显示 tail -n 30 "$DDLOG",并按结果表处理(此处的 403 通常表示区域错误 → 第 2 步)。
  • 报告身份调用返回的已验证组织/邮箱。
  • 所有凭据都保存在 .env 中(DD_SITE、DD_API_KEY,以及通过路径 C 创建账户时的 DD_SIGNUP_PASSWORD)— 直接写入文件,绝不回显。清理注册临时文件以及 OAuth state 和 callback 文件:rm -f "${TMPDIR:-/tmp}"/dd-signup-$(id -u).* "${TMPDIR:-/tmp}"/dd-oauth-$(id -u).state "${TMPDIR:-/tmp}"/dd-oauth-$(id -u).cb。
  • 下游移交 — 保留 OAuth 令牌。 保留 ${TMPDIR:-/tmp}/dd-oauth-$(id -u).token(0600),不要删除。下游检测会重用此 Bearer 令牌来配置普通 API 密钥无法创建的资源 — 尤其是 RUM 应用。此令牌有效期短且有作用域限制;完成设置后,由引导调用方(例如编排器)将其删除(rm -f "${TMPDIR:-/tmp}"/dd-oauth-$(id -u).token)。如果单独运行检测,请在完成后自行删除。
  • 返回:“账户已准备就绪。现在可以运行设置/检测步骤了。”(例如 studio-setup、browser-rum-setup、llm-observability-setup 或其他任何 *-setup 技能)。

↳ 清单: 勾选 5. 已就绪 — 移交 — 显示已全部完成的清单,让用户知道整个流程已完成。


故障排查与参考

如果某个步骤失败,请参阅 references/troubleshooting.md — 症状→解决方法表(区域错误、OAuth 状态不匹配、无头模式退出、Path-C 注册错误等),以及设计决策和临时状态说明。

评论

支持 Markdown