For production I would want to run this in Docker in some sort of a portable fashion.
Looking at the documentation it seems that you have to manually enter the password when you start up step-ca. That's not really going to work for automated setups. You need to be able to inject secrets from environment variables, or these days, Kubernetes secrets.
There's also the issue of backing up your CA secrets, e.g. if your step-ca process dies and you want to restart it somewhere else. That may be out of scope for step-ca though and handled through some other process, which is fine.
Might be good to add some documentation on how to set this up in a high availability fashion so it is not a single point of failure.
I do like the relative simplicity of this compared to all the other CA solutions out there. Good luck and thanks for the work.
Do https://hub.helm.sh/charts/smallstep/step-certificates & https://hub.docker.com/r/smallstep/step-ca tick this box for you?
> Looking at the documentation it seems that you have to manually enter the password when you start up step-ca... environment... kubernetes secrets
There are a couple options here. You're only prompted for a password if your intermediate signing key (at `$(step path)/secrets/intermediate_ca_key` by default) is encrypted with a password. You can create your own signing key (e.g., with `step certificate create`) or remove the password (e.g., with `step crypto change-pass --no-password`) and you won't be prompted for one.
The `step-ca` binary also takes a `--password-file` flag. We chose to take this from file vs. environment or directly as a flag because files are the easiest thing to secure in general... and we're all about misuse resistance. If you really want to use a string or an environment variable you can use bash process substitution (e.g., `--password-file <(echo "pass")` or `--password-file <(echo $PASS)`).
We're also working on PKCS#11 HSM support and will be supporting cloud HSM/KMSs on all the popular clouds, which is probably the best and most secure option for most people.
> There's also the issue of backing up your CA secrets, e.g. if your step-ca process dies and you want to restart it somewhere else.
Yea this is super tricky. I think HSMs are probably the right answer. As it stands, the password protection on the signing keys mean it's somewhat ok (if not best practice) to backup the keys. Really though, the whole system is designed to make intermediate and even root rotation fairly easy so there's that option, too.
This is an area where we're still improving and definitely appreciate feedback from anyone who has thoughts.
> Documentation on how to set this up in a high availability fashion
Yea good call. We need that.
For anyone who's reading this you should be aware that the CA just needs a root and intermediate cert in `$(step path)/certs` and an intermediate key in `$(step path)/secrets`. You don't have to create these keys with `step ca init`. You can use the lower level `step certificate create` command group to create a second intermediate that hangs off an existing root, for example.
> I do like the relative simplicity of this compared to all the other CA solutions out there. Good luck and thanks for the work.
Thanks so much! <3.
Edit:
If you're doing k8s stuff also check out:
- https://github.com/smallstep/autocert
- https://github.com/smallstep/step-issuer
If you're using Envoy/Istio we're also iterating on this:
That said, even AWS's crappy implementation is super useful, and really the only good way to do this (that I know of?). We've tried to mitigate this risk somewhat by making tokens single use. I'd like to also add a way to send a token to `step-ca` to say "this server doesn't need a certificate" that basically marks the instance as "used" without issuing anything. If everything that uses IIDs did this, and you ran through all of your services at startup and either authenticated or said "I never need to use this service", it would provide some protection.
Still, to your point, AWS should fix their shit.
From a mile high view, the thing that makes step somewhat different is the heavy emphasis on usability and reducing overall complexity of managing your own PKI holistically.
So, even if smallstep is more complete in a feature-for-feature comparison to alternatives, the primary focus on ergonomics and filling the "humanized" tooling gap is why you might pick it over another tool... depending on your needs.
In a sense step is to cfssl/openssl as httpie is to curl. You can accomplish a lot of the same things, but they're at different levels as far as mental tax and overall approachability.
- CFSSL by default runs open -- it's an unauthenticated API that'll sign anything. Figuring out how to securely authenticate to the CA is one of the hardest parts of automated enrollment. `step` & `step-ca` solve this for you.
- Building on the last point, there are multiple ways to authenticate to `step-ca` for various scenarios: one-time tokens, OAuth OIDC (SSO)[1], and now instance identity documents for VMs (more coming soon)
- The `step` command-line tool integrates with `step-ca` and makes the entire enrollment process super easy -- we focused a lot on usability (and misuse resistance)
- `step` also helps with other certificate management workflows[2] like root certificate distribution, root federation, root certificate (un)installation[3], certificate renewal, and (passive) revocation
- `step` is also useful as a generic swiss army knife for security tech like JWTs, JWKs, NaCl, OAuth, and more... not necessary relevant for this comparison, but useful[4]
This might be unfair... but I think philosophically the projects serve different purposes. CFSSL was created to serve CloudFlare's specific internal PKI needs, and it does that well, and it was awesome of them to open source it. `step` & `step-ca` was created because we believe everyone deserves great internal public key infrastructure and there's a tooling gap. So I think we're more interested in addressing a broader variety of use cases than CFSSL is.
There are some definite advantages of CFSSL though. Someone can probably extend this list and I'd love to discuss, but some obvious ones from my perspective are:
- They have a bigger community (at least for now :)
- They've been around longer
- There's more documentation out there about how to do things with CFSSL (see point #1)
Functionally, I think the only thing that CFSSL has that we don't at the moment is "active" certificate revocation -- CRLs & OCSP. We think short-lived certificates[5] are a better approach, and design for that primarily, but we're planning to fill this gap soon so at that point I think we'll be parity+ with CFSSL.
[1] https://smallstep.com/blog/easily-curl-services-secured-by-h...
[2] https://smallstep.com/docs/cli/ca/#commands
[3] https://smallstep.com/docs/cli/certificate/install/
[4] https://github.com/smallstep/cli/blob/master/README.md#Featu...
Am I understanding it correctly that step-ca can be configured to either 1) hand out certs for any CN or 2) only hand out certs for the machine's FQDN according to the instance metadata? In essence, the "any CN" mode is only useful for knowing that this instance is one of your own (but exactly which one is totally on the honor system), and the "FQDN only" mode is useful if you use your cloud provider's FQDNs for your hosts. Do I have that correct?
Still, this is hand-wavey and complicated and not ideal from a security perspective. It's a lot better than not having certificates at all, but it'd be even better if this gap were closed.
To close this gap we need some sort of enrollment process. The reason we didn't add this for MVP is it's kind of complicated. I think we'd need some policy at the CA that maps VM identities to the workload identities the VM is authorized to run. We need to figure out what would run this enrollment step to add the mappings (probably different for different stacks) and how that thing would authenticate to the CA.
We've also been a bit reluctant to add ad-hoc policy stuff to the CA because we have a generic policy solution that we've been working on. Once that's released it'll give us a much better foundation for this sort of stuff.
Finally, there are other ways to build a stronger enrollment mechanism today. We have a JWT-based one-time-token authentication mechanism[1] that you can use, where a "provisioner" (e.g., something in your CD pipeline like Puppet or Kubernetes) issues a one-time token for a workload to get a certificate from `step-ca`. In this flow the JWT contains the workload's identity, so whatever issues the JWT controls certificate enrollment. This flow has pretty much the same characteristics as an IID+enrollment flow.
Finally, we have ACME support coming soon (next week, actually). So that'll be another option if you want a stronger binding to an instance's FQDN.
Hope this makes sense. Happy to answer any additional questions!
[1] https://smallstep.com/docs/design-document/#jwk-provisioner
If you ever have a reason to check out the `step` / `step-ca` toolchain I'd love to chat about the differences you see. Message me here or shoot me an email (mike at smallstep).
XCA is a gui for dealing with making certs. For me even as a technical user, i prefer it more than CLI.