{
  "slug": "flyctl-certificates-use-the-machines-api-with-custom-certificate-uploads-and-dom-8f01b1631cf2",
  "title": "flyctl certificates use the Machines API with custom certificate uploads and domain ownership verification",
  "tools": [
    "flyctl"
  ],
  "tags": [
    "agent"
  ],
  "introduced_at": "2026-02-12T19:31:03.000Z",
  "announced_at": "2026-02-12T19:31:03.000Z",
  "effective_at": null,
  "date_basis": "source-publication",
  "status": "unknown",
  "how": {
    "incantation": "When managing an app certificate, use `fly certs` commands. Import a custom PEM certificate and key with `import`; use `setup` for DNS instructions and `check` after adding the ownership record.",
    "examples": [
      "fly certs import <hostname> -a <app> --fullchain <path/to/fullchain.pem> --private-key <path/to/private-key.pem>",
      "fly certs setup <hostname> -a <app>",
      "fly certs check <hostname> -a <app>"
    ],
    "gotchas": [
      "Version: v0.4.11",
      "<hostname> (required): Hostname for the certificate.",
      "-a, --app <app>: Application name; the command requires an app name, which may come from app configuration instead.",
      "--fullchain <path> (required): Path to the certificate chain file in PEM format.",
      "--private-key <path> (required): Path to the private key file in PEM format.",
      "Prerequisite: The certificate import command requires an authenticated Fly session and an app name.",
      "Prerequisite: Provide the certificate chain and private key in PEM format. Domain ownership must be verified through DNS before the imported certificate becomes active.",
      "Certificates are primarily serviced through the Machines API rather than GraphQL.",
      "The DNS entry can verify domain ownership in certain circumstances."
    ]
  },
  "why_it_matters": "Manage certificates for an application, including uploading a custom certificate or verifying domain ownership.",
  "sources": [
    "https://github.com/superfly/flyctl/releases/tag/v0.4.11",
    "https://github.com/superfly/flyctl/pull/4739",
    "https://github.com/superfly/flyctl/blob/v0.4.11/internal/command/certificates/root.go"
  ],
  "rank": 0.95031,
  "judge": {
    "publish": true,
    "judge_model": "codex-cli/gpt-6-luna+typesafe/jev-1.13.0",
    "prompt_version": "extract-v7+enrich-v2+judge-v2x3-rejudge+jev-publish-v1"
  },
  "review_state": "approved",
  "provenance": {
    "run_id": "wave1b-20261016",
    "verdict_id": "wave1b-20261016:wave1b-20261016-173ff0941bcc4ef3-0:rescue",
    "evidence_hash": "7ad4e25339fb2b10d47ad1abcd60d7768c0e3fe00bc4d52a51fc0ec45433748d"
  },
  "review": {
    "draft_hash": "842346ca3eb893379fa21abb5570c1fa9887b94bd5e50bd058749d43d5467b86",
    "reviewer": "publication-gate",
    "reviewed_at": "2026-10-07T00:00:00.000Z",
    "decision": "wave1b-20261016:rescue",
    "reason": "Rescue path: first rejected only because the extracted card lacked usage; judged again on the enriched card, 3 of 3 judge runs approved with p_yes >= 0.9 (mean 0.95 >= 0.9; 2 needed) and Jev gave 0.76 (>= 0.6 needed)."
  }
}
