Dstack-TEE / Dstack-TEE/dstack-examples

Feature: ACME DNS-01 challenge delegation (CNAME alias) for least-privilege DNS tokens

未关闭
#103 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看
主要语言
Python
星标
27
派生
26
平均合并
1 小时 25 分钟
30 天内合并 PR
7

描述

## Problem

dstack-ingress issues certs via ACME **DNS-01**, which requires a DNS provider API token that can edit the **served domain's own zone** (to write the `_acme-challenge` TXT, and — per `entrypoint.sh` — to set the A record and CAA).

In our deployment the served name (e.g. `svc.example.com`) lives under a **shared production zone** (`example.com`) that holds many unrelated production records. Handing the enclave a token for that zone is too broad:

- Cloudflare API tokens scope only to **zone level** — there is no way to restrict a token to a single subdomain/record.
- Managing the subdomain as its own Cloudflare zone requires an **Enterprise** plan.

So today we'd have to give the enclave a token that can edit our **entire** `example.com` zone, which we can't accept.

## Proposed feature: DNS-01 challenge delegation (CNAME alias)

Let the operator delegate **only the `_acme-challenge`** to a separate zone they fully control, so the enclave's token never touches the production zone:

1. Operator adds one static record in the production zone:
`_acme-challenge.svc.example.com CNAME .`
2. dstack-ingress writes the challenge TXT into `` (its token scoped **only** to that zone). Let's Encrypt follows the CNAME during validation.

This is a standard least-privilege ACME pattern (acme.sh `--challenge-alias`, lego, cert-manager, and Cloudflare's own "Delegated DCV" all support it), and it fits dstack's zero-trust ethos.

## Design sketch (opt-in, non-breaking)

- New env `ACME_CHALLENGE_ALIAS=`; unset ⇒ current behavior, unchanged.
- When set, run certbot with `--manual --preferred-challenges=dns` + auth/cleanup hooks that **reuse the existing `dns_providers` abstraction** to write the TXT under the alias zone instead of `_acme-challenge.`.

## Important: CAA handling (needs an explicit decision)

`entrypoint.sh` currently auto-sets the accounturi CAA
(`letsencrypt.org;validationmethods=dns-01;accounturi=$ACCOUNT_URI`) on the served domain, using the same token. In delegation mode the token **cannot** touch the served domain's zone, so this auto-set won't work — and the current code treats a CAA-set failure as `not critical`, which would **silently drop the accounturi lock** (the forge-prevention against a non-TEE account issuing a cert for the domain).

To avoid silently weakening security, in delegation mode the feature should:
- **print the exact CAA record** the operator must set statically in the served zone (including the account URI), and
- **verify the CAA is present / warn loudly if absent**, instead of silently continuing.

This keeps the "only the TEE's ACME account can issue" guarantee **explicit**, rather than silently lost.

贡献指南

打开贡献指南

调研方向

Start with entrypoint.sh and the existing dns_providers abstraction; trace the current ACME invocation, TXT handling, and CAA failure path. Review the proposed ACME_CHALLENGE_ALIAS flow and certbot manual auth/cleanup hooks. Done means alias-zone TXT delegation works without production-zone access, while the exact accounturi CAA is printed and verified or loudly reported absent.

由索引模型根据 Issue 内容生成。

评估

技术栈
python, shell
领域
cloud, devops, security
Issue 类型
功能
难度
5/5
预计耗时
一周以上
活跃度
冷清
描述清晰度
基本清楚
新手友好度
45/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。