{"id":39076031,"url":"https://github.com/cloud-gov/external-domain-broker","last_synced_at":"2026-01-17T18:26:44.579Z","repository":{"id":38024158,"uuid":"251648974","full_name":"cloud-gov/external-domain-broker","owner":"cloud-gov","description":"Cloud Foundry service broker to manage Cloud Front, ALBs and Let's Encrypt","archived":false,"fork":false,"pushed_at":"2025-12-02T14:22:21.000Z","size":2197,"stargazers_count":3,"open_issues_count":6,"forks_count":2,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-12-05T12:13:21.026Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cloud-gov.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2020-03-31T15:37:11.000Z","updated_at":"2025-12-02T14:22:24.000Z","dependencies_parsed_at":"2024-01-18T15:09:48.778Z","dependency_job_id":"bedbf6be-2ee4-4846-8bc2-e0e6fb3204f4","html_url":"https://github.com/cloud-gov/external-domain-broker","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/cloud-gov/external-domain-broker","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloud-gov%2Fexternal-domain-broker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloud-gov%2Fexternal-domain-broker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloud-gov%2Fexternal-domain-broker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloud-gov%2Fexternal-domain-broker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cloud-gov","download_url":"https://codeload.github.com/cloud-gov/external-domain-broker/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloud-gov%2Fexternal-domain-broker/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28515473,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-17T17:57:59.192Z","status":"ssl_error","status_checked_at":"2026-01-17T17:57:52.527Z","response_time":85,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-17T18:26:43.775Z","updated_at":"2026-01-17T18:26:44.569Z","avatar_url":"https://github.com/cloud-gov.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Cloud Foundry Domain Broker\n\nCloud Foundry service broker to manage AWS CloudFront, AWS ALBs and Let's Encrypt.\n\nLike the [cf-domain-broker](https://github.com/18F/cf-domain-broker), this\nbroker combines the features of the\n[cf-cdn-service-broker](https://github.com/18F/cf-cdn-service-broker) and\nthe [cf-domain-broker-alb](https://github.com/18F/cf-domain-broker-alb). It\nprovisions Let's Encrypt certificates for a given domain, and configures\neither AWS ALBs (created out-of-band) or an AWS CloudFront distribution\n(created by the broker) to use that certificate.\n\n## AWS GovCloud \n\nIt's important to note this broker and it's configuration was designed first\nand foremost for AWS GovCloud, which has some limitations when it comes to\nglobal configurations. For example, Route53 is not avaialble in GovCloud as\nit's a global service, so while the domain broker can be deployed as a Cloud\nFoundry app in GovCloud, it still needs to cross the boundary into the AWS\ncommercial cloud.\n\nThis also means the broker expects to use a different IAM user and configuration\nfor ALBs and CloudFront distributions.\n\nThere's nothing preventing using AWS commercial resources (IAM users, ALBs, etc) where\ngovcloud resources are expected, so a commercial-only deployment should be possible\nwithout any modification. Similarly, if CloudFront and Route53 were to be brought\ninto govcloud, nothing would prevent using govcloud resources where commercial resources\nare expected.\n\n## Usage\n\nWhen users request a domain service instance, this broker will validate some\nprerequisite DNS configuration then provision a Let's Encrypt certificate, \nan ELB and a CloudFront CDN, and wire them all up together. \n\n### Let's Encrypt Challenge Challenges\n\nWe have some constraints that make the [Let's Encrypt Challenge\nprocess](https://letsencrypt.org/docs/challenge-types/) \"difficult\":\n\n#### `HTTP01`\n\n`HTTP01` with CloudFront gives us a chicken-and-egg problem, in that CloudFront\nwill not answer to a custom domain, even for HTTP, without [verifying ownership\nof that domain via a valid SSL\ncertificate](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/cnames-and-https-requirements.html#https-requirements-certificate-issuer):\n\n\u003e If you want to use an alternate domain name with your CloudFront\n\u003e distribution, you must verify to CloudFront that you have authorized rights\n\u003e to use the alternate domain name. To do this, you must attach a valid\n\u003e certificate to your distribution, and make sure that the certificate comes\n\u003e from a trusted CA that is listed on the Mozilla Included CA Certificate List.\n\u003e **CloudFront does not allow you to use a self-signed certificate to verify your\n\u003e authorized rights to use an alternate domain name.**\n\n#### `TLS-ALPN01`\n\nWe still need to fully investigate `ALPN01`, and its support in CloudFront.\nIt's not clear if the `ALPN01` certificate is a self-signed cert - if so, we'll\nlikely hit the same CloudFront limitation listed above.\n\nInvestigation pointers:\n\n- [CloudFront supports HTTP/2](https://aws.amazon.com/about-aws/whats-new/2016/09/amazon-cloudfront-now-supports-http2/)\n- [ALPN is the required SSL implementation for HTTP/2](https://en.wikipedia.org/wiki/Application-Layer_Protocol_Negotiation)\n- [Dehydrate](https://github.com/lukas2511/dehydrated/blob/master/docs/tls-alpn.md) bash ACME client can generate ALPN certs.\n\n#### `DNS01`\n\nWe do not have access to or control over DNS for the application, so we cannot\nautomate the `DNS01` challenge.\n\n#### Our Solution - CNAMES of CNAMES\n\nBecause of these limitations, we have users create CNAME (or ALIAS) records pointing\nto records within our control. This allows us to validate the user's input ahead of time,\nhopefully reducing the number of failures at provision time. It also allows us to manage\nrenewals using TXT records, which eliminates the S3 config from the previous iterations\nof the broker. Finally, it should make creating a process to change between CDN and ALB\ninstances possible without risk of downtime.\n\nBefore creation, customers create a CNAME record for `_acme-challenge.\u003ctheir-domain\u003e`\npointed to `_acme-challenge.\u003ctheir-domain\u003e.\u003cour-configured-domain\u003e`. This allows us to\nupdate TXT records on their behalf, which in turn allows us to solve DNS-01 challenges for\nthem.\nBefore, during, or after provisioning, they add a CNAME record for `\u003ctheir-domain\u003e` pointing\nto `\u003ctheir-domain\u003e.\u003cour-configured-domain\u003e`, which routes traffic to their site.\n\n## Configuration\n\nThe Broker can be configured via the following environment variables:\n\n| Variable                         |                                                             |\n| ---------------------------------|-------------------------------------------------------------|\n| FLASK_ENV                        | Environment name for Flask                                  |\n| SECRET_KEY                       | Flask secret key                                            |\n| BROKER_USERNAME                  | Username for the broker                                     |\n| BROKER_PASSWORD                  | Password for the broker                                     |\n| DATABASE_ENCRYPTION_KEY          | Key used to encrypt database storage                        |\n| ROUTE53_ZONE_ID                  | Zone ID of Route53 zone for hosted zone for DNS_ROOT_DOMAIN |\n| DNS_ROOT_DOMAIN                  | Intermediate domain users point their DNS to                |\n| DEFAULT_CLOUDFRONT_ORIGIN        | CloudFront origin used for instances that route to CF apps  |\n| AWS_GOVCLOUD_REGION              | Region to use for AWS govcloud services                     |\n| AWS_GOVCLOUD_SECRET_ACCESS_KEY   | Access key for AWS govcloud services                        |\n| AWS_GOVCLOUD_ACCESS_KEY_ID       | Access key ID for AWS govcloud services                     |\n| AWS_COMMERCIAL_REGION            | Region to use for commercial AWS services                   |\n| AWS_COMMERCIAL_SECRET_ACCESS_KEY | Access key for commercial AWS services                      |\n| AWS_COMMERCIAL_ACCESS_KEY_ID     | Access key ID for commercial AWS services                   |\n| ALB_LISTENER_ARNS                | comma-separated list of ARNs for AWS ALB Listeners to use   |\n| DEDICATED_ALB_LISTENER_ARN_MAP      | JSON object mapping ALB listener ARNs to dedicated organization GUIDs  |\n| SMTP_HOST                        | Hostname of SMTP server (for alerts)                        |\n| SMTP_PORT                        | Port for SMTP server (for alerts)                           |\n| SMTP_CERT                        | Certificate chain to trust for SMTP server (for alerts)     |\n| SMTP_USER                        | Username for authentication with SMTP server (for alerts)   |\n| SMTP_PASS                        | Password to use for SMTP server (for alerts)                |\n| SMTP_FROM                        | Email address to send emails from (for alerts)              |\n| SMTP_TO                          | Email address to send alert emails to                       |\n|                                  |                                                             |\n\n## IAM Policies\n\nAs this broker manages ELBs, IAM Certificates, CloudFront and other\nAWS resources, it requires an IAM policy that allows access to those APIs.\nWe've [provided a sample govcloud policy](/docs/sample_iam_policy_govcloud.json)\nand [a sample commercial policy](/docs/sample_iam_policy_commercial.json), but\nyou're responsible for auditing your own security policies. No warranty, etc, etc.\n\n## Pipeline Configuration\n\nThis broker leverages [Concourse](https://concourse-ci.org) for its deployment\nautomation, but it's not dependent on it. You can find example and live\nconcourse configuration files in [the `ci/` directory](/ci).\n\n## History\n\nThis broker supersedes the\n[cf-domain-broker](https://github.com/cloud-gov/cf-domain-broker), the\n[cf-cdn-service-broker](https://github.com/cloud-gov/cf-cdn-service-broker) and\nthe [cf-domain-broker-alb](https://github.com/cloud-gov/cf-domain-broker-alb).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloud-gov%2Fexternal-domain-broker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcloud-gov%2Fexternal-domain-broker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloud-gov%2Fexternal-domain-broker/lists"}