HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
letsencrypt
boulder
Go2015–2025
letsencrypt / boulder

boulder

An ACME-based certificate authority, written in Go.

33Distinct people
37Mentions
0Explicit recommenders
5.8KGitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

An ACME-based certificate authority, written in Go.

GitHub

Where it is used

No documented product use was verified in the last source check.

What people are saying

No recommendation phrase was found in the indexed comments.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

Mentioned in the same Hacker News threads. That is not proof they are substitutes.

This week on Hacker News

Nov 7–Nov 14 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/14/2026, 1:49:46 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year37 dated mentions

Observed mentions: 2015-01-16 20:12:21 UTC to 2025-12-10 01:41:29 UTC.

02468102015-01-01 00:00:00 UTC to 2016-01-01 00:00:00 UTC (exclusive): 6 mentions; 1 submissions, 5 comments20152016-01-01 00:00:00 UTC to 2017-01-01 00:00:00 UTC (exclusive): 9 mentions; 0 submissions, 9 comments2017-01-01 00:00:00 UTC to 2018-01-01 00:00:00 UTC (exclusive): 6 mentions; 1 submissions, 5 comments2018-01-01 00:00:00 UTC to 2019-01-01 00:00:00 UTC (exclusive): 4 mentions; 0 submissions, 4 comments2019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 5 mentions; 0 submissions, 5 comments20202021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments2023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2025-01-01 00:00:00 UTC to 2026-01-01 00:00:00 UTC (exclusive): 3 mentions; 0 submissions, 3 comments2025

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20152015-01-01 00:00:00 UTC2016-01-01 00:00:00 UTC615
20162016-01-01 00:00:00 UTC2017-01-01 00:00:00 UTC909
20172017-01-01 00:00:00 UTC2018-01-01 00:00:00 UTC615
20182018-01-01 00:00:00 UTC2019-01-01 00:00:00 UTC404
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC101
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC505
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC101
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC202
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC000
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC000
20252025-01-01 00:00:00 UTC2026-01-01 00:00:00 UTC303

From the project README

An excerpt from the repository, fetched Nov 13, 2026.

Read the project’s introduction
Boulder - An ACME CA This is an implementation of an ACME-based CA. The ACME protocol allows the CA to automatically verify that an applicant for a certificate actually controls an identifier, and allows subscribers to issue and revoke certificates for the identifiers they control. Boulder is the software that runs Let's Encrypt. Contents Overview Setting up Boulder Development Working with Certbot Working with another ACME Client Production Contributing License Overview Boulder is divided into the following main components: Web Front Ends (one per API version) Registration Authority Validation Authority Certificate Authority Storage Authority Publisher CRL Updater This component model lets us separate the function of the CA by security context. The Web Front End, Validation Authority, CRL Storer, and Publisher need access to the Internet, which puts them at greater risk of compromise. The Registration Authority can live without Internet connectivity, but still needs to talk to the Web Front End and Validation Authority. The Certificate Authority need only receive instructions from the Registration Authority. All components talk to the SA for storage, so most lines indicating SA RPCs are not shown here. CA ---------> Publisher ^ | Subscriber -> WFE --> RA --> SA --> MariaDB | ^ Subscriber server <- VA <----+ | | Browser -----> S3 <----- CRL Storer/Updater Internally, the logic of the system is based around five types of objects: accounts, authorizations, challenges, orders and certificates, mapping directly to the resources of the same name in ACME. Requests from ACME clients result in new objects and changes to objects. The Storage Authority maintains persistent copies of the current set of objects. Boulder uses gRPC for inter-component communication. For components that you want to be remote, it is necessary to instantiate a "client" and "server" for that component. The client implements the component's Go interface, while the server has the actual logic for the component. A high level overview for this communication model can be found in the gRPC documentation. The full details of how the various ACME operations happen in Boulder are laid out in the Boulder implementation details. Setting up Boulder Development Boulder has a Dockerfile and uses Docker Compose to make it easy to install and set up all its dependencies. This is how the maintainers work on Boulder, and is our main recommended way to run it for development/experimentation. It is not suitable for use as a production environment. While we aim to make Boulder easy to setup ACME client developers may find Pebble, a miniature version of Boulder, to be better suited for continuous integration and quick experimentation. We recommend setting git's fsckObjects setting before getting a copy of Boulder to have better integrity guarantees for updates. Clone the boulder repository: git clone https://github.com/letsencrypt/boulder/ cd boulder Additionally, make sure you have Docker Engine 1.13.0+ and Docker Compose 1.10.0+ installed. If you do not, you can follow Docker's installation instructions. We recommend having at least 2GB of RAM available on your Docker host. In practice using less RAM may result in the MariaDB container failing in non-obvious ways. To run our standard battery of tests (lints, unit, integration): ./t.sh To run all unit tests: ./t.sh -u To run specific unit tests (example is of the ./va directory): ./t.sh -u -p ./va To run all integration tests: ./t.sh -i To run unit tests and integration tests with coverage: ./t.sh -ui -c --coverage-dir=./test/coverage/mytestrun To run specific integration tests (example runs TestGenerateValidity and TestWFECORS): ./t.sh -i -f TestGenerateValidity/TestWFECORS To do any of the above, but using the "config-next" configuration, which represents a likely future state (e.g. including new feature flags): ./tn.sh -your -options -here To start Boulder in a Docker container, first run: docker compose run bsetup this will write the necessary certificates into test/certs/[.softhsm-tokens,ipki,webpki]; You only need to run this once to create the certificates. If you need to remove all of the certificates and start over, you can remove the directories ./test/certs/.softhsm-tokens, ./test/certs/ipki, and ./test/certs/webpki and re-run docker compose run bsetup. Then run: docker compose up The configuration in docker-compose.yml mounts your boulder checkout at /boulder so you can edit code on your host and it will be immediately reflected inside the Docker containers run with docker compose. If you have problems with Docker, you may want to try removing all containers and volumes. By default, Boulder uses a fake DNS resolver that resolves all hostnames to 127.0.0.1. This is suitable for running integration tests inside the Docker container. If you want Boulder to be able to communicate with a client running on your host instead, you should find your host's Docker IP with: ifconfig docker0 | grep "inet addr:" | cut -d: -f2 | awk '{ print $1}' And edit docker-compose.yml to change the FAKE_DNS environment variable to match. This will cause Boulder's stubbed-out DNS resolver (sd-test-srv) to respond to all A queries with the address in FAKE_DNS. If you use a host-based firewall (e.g. ufw or iptables) make sure you allow connections from the Docker instance to your host on the required validation ports to your ACME client. Alternatively, you can override the docker-compose.yml default with an environmental variable using -e (replace 172.17.0.1 with the host IPv4 address found in the command above) docker compose run --use-aliases -e FAKE_DNS=172.17.0.1 --service-ports boulder ./start.py Running tests without the ./test.sh wrapper: Run unit tests locally, without docker (only works for
Read the full README on GitHub

What Hacker News says

37 sources
https://github.com/letsencrypt/boulder You can find a docker-compose.yml file to get some idea. Appears to be using MariaDB. They shut down OCSP responders and expiry email reminders, so there really is no need to have a database apart from rate limits, auth data, and caching. For Certificate Transparency, they are submitted to Google and CloudFlare run trees but I don't think LetsEncrypt run their own logs.
In 10 Years of Let's Encrypt
Operating a private CA is trivial, there are packages to automate it at every level from simple manual scripting to fully-automated ACME servers such as Boulder[0]. For proprietary software it's idiomatic to use a private CA for securing connections to a central server, to avoid the risk of DNS hijacking or a malicious third-party CA. For open-source software it will, definitionally, allow substituting different server key validation options for users who prefer to run their own servers. The only real problem QUIC's mandatory TLS causes is that localhost development becomes marginally more difficult, but even as someone who loves running my in-development stuff on localhost it's clear that the security of the internet as a whole is of far greater value. [0] https://github.com/letsencrypt/boulder
In Comparing TCP and QUIC
Why are you assuming that their workload includes just one query per emitted certificate? The reality is that they are storing information during challenges, implementing rate limiting per-account, supporting OCSP validation and a few other things. You can investigate further if you really want to see the queries that they make against the database since their software (Boulder) is open source [1]. Most queries are in the files in the "sa" (storage authority) folder. [1] https://github.com/letsencrypt/boulder/
In The database servers powering Let's Encrypt
Why TLS-SNI-01 was disabled: https://community.letsencrypt.org/t/2018-01-09-issue-with-tl... Explanation that renewals will be disallowed after 1 year deprecation period: https://community.letsencrypt.org/t/march-13-2019-end-of-lif... And as you seem to be talking about ACMEv1/v2 instead of TLS-SNI-01 (which I originally thought); it will be supported as long as June 2021 in some cases: https://community.letsencrypt.org/t/end-of-life-plan-for-acm... ACMEv2 was introduced, because it is much closer to the actual spec. Enforcing this ensures that there are actually ACME implementations out there, instead of proprietary "Let's Encypt ACME" implementations. https://tools.ietf.org/html/rfc8555 https://github.com/letsencrypt/boulder/blob/master/docs/acme... To me this seems like a sensible compromise between backwards compatibility and their mi
Read the rest
ssion for standardized automated renewals.
In Letsencrypt, the Good, the Bad and the Ugly
For context in terms of what caused this, here's the PR which I assume fixed the bug in question: https://github.com/letsencrypt/boulder/pull/4690 It looks like a nasty and subtle pass-by-reference of a for-range local variable, although I'm having trouble figuring out where the reference is stored: https://github.com/letsencrypt/boulder/blob/542cb6d2e06e756a... I've spent plenty of time hunting down similar bizarre bugs in Go code as well, where the called function ~implicitly~ takes a pointer to the iteration variable and stores it somewhere. Each iteration of the for loop updates the stack-local in-place, and later reads of the stored reference will not read the original value. It's hard to spot from the actual call site :/ EDIT: This was an explicitly taken `&v` reference, but the same thing can also happen implicitly, if you call a `
Read the rest
func (x *T) ...` method on the variable.
In Revoking certain certificates on March 4
> what I hear is "they feel they have to support it, and as long as they have to support it they're going to do it right, unlike other CAs". Did you hear that from @cpu too? Is it an actual quote, or is this you paraphrasing again and it might be completely wrong? Regardless this did prompt me to go back and look at what became https://github.com/letsencrypt/boulder/pull/3726 and confirm that yeah, they still don't get it. Must try harder. I thought I did a pretty good job of spelling out what needs to happen to have confidence here, using an example from EMV of what not to do - but it didn't have the desired effect and this is still the same "parse first, regret later" approach that is ultimately why that PR even exists in the first place (Let's Encrypt were mis-parsing CAA records and discovered in post mortem their records weren't good
Read the rest
enough to actually figure out the impact from the incident). > Another thing you're well aware of was that one of the key design goals for SSL/TLS was not to depend on the DNS for security. I can't figure out any way to squint at this which makes it both true and non-trivial. In practice what Netscape did was punt to the existing Certificate Authorities and carefully avoid asking awkward questions about how they did it. This achieves a goal "not to depend on the DNS" only in the same sense that that chap the other day was able "not to depend on a mobile phone" by just getting a friend to receive all their calls for them and pass on messages... For many years what the Certificate Authorities actually did was not officially documented anywhere. But we do have some amazing patents they filed to protect their "innovative" solutions. They're uh... they're very bad. Go read some, you can laugh now because none of this is permitted any more. What we know of the unpatented stuff they did was mostly worse. Would you be surprised that OCRing the images from anti-spammer WHOIS websites was an actual thing that an actual trusted Certificate Authority was doing to figure out the contact email address for a domain? Guess how reliable that was...
In DNSSEC root key signing ceremony postponed because they can't open a safe
RSA: The more shortcuts you take in your RSA keygen, the more likely it is that an adversary can just guess your keys without (impossibly) trying all the possibilities. This necessarily follows from how such shortcuts work, and should be guarded against in an implementation. In that sense ROCA is the same as the Debian Weak Keys. And so the Web PKI did the same thing about both, the CA examines the public key, it makes the same determination an attacker would make, but rather than attacking you it rejects your certificate request. You can actually read the code in Boulder (the Let's Encrypt software) to see this in action‡. If you actually pick random numbers that are roughly the right size, reject composites, and use your random primes to make an RSA key, this method works. But it's slow. And it's obvious that you needn't pick the whole
Read the rest
number at random, the bottom bit must be '1' because it's prime. And once you start optimizing you soon have a very complicated key generation which opens lots of opportunities for things to go wrong... ‡ https://github.com/letsencrypt/boulder/pull/3189 Edited to add: The work that eventually led to ROCA is really fascinating. The researchers spent lots of time characterising RSA key generators. Their first paper is basically "If you show me fifty keys you made, I can guess how you made them" and that's already pretty interesting in some applications. In that work they found that a particular type of key generator was doing something _very strange_ but deadlines are deadlines and so their paper stops at remarking how strange it is. ROCA is basically what they found when they kept investigating.
In ROCA vs. ROBOT: An Eternal Golden Braid
The 20 per week limit has been an issue for large organizations with tons of different subdomains managed by different groups. Universities are a good example: you might have things like bobsmith.faculty.example.edu, cs101.compsci.example.edu, etc., which all count against the example.edu rate limit. This can especially be a problem because the renewal exception to the rate limit doesn't work like you might expect. If a particular cert (meaning the exact same set of domains) has already been created, it can be renewed regardless of whether it would exceed the rate limit - but it still counts against the rate limit. If 45 certs have already been renewed in the last week, you can only create 5 new ones. If 80 certs have been renewed in the last week, you can't create any new ones. They plan to change this, but it hasn't happened yet: https:
Read the rest
//github.com/letsencrypt/boulder/issues/2800 Some organizations have gotten rate limit exceptions to handle this particular issue. Maybe they looked at some internal metrics and decided raising it to 50 would reduce the number of exceptions they have to make while still curbing misuse.
In Let's Encrypt Root Trusted by All Major Root Programs

Showing the 15 most recent of 37 sources. Enable JavaScript to search and browse every indexed mention.

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.