sig-auth.git

git clone https://git.crispbyte.dev/sig-auth.git

 1# sig-auth
 2
 3Signature authentication service designed to be used as middleware for Caddy.
 4
 5# About
 6
 7This project was created to test an idea I had to use [RFC9421: HTTP message signatures](https://www.rfc-editor.org/rfc/rfc9421.html) for authentication. The way it works is simple.
 8
 91. The user registers a public key, and the server sends a key ID back
102. The user signs the HTTP request with their private key, passing in the key ID
113. The server verifies the signature and returns a response with the user ID in a header
12
13Use this as middleware for a reverse proxy, and HTTP message signatures can be used to identify the user without any shared secrets. It could even be adapted, with some configuration changes, to use an API key without revealing it to the user.
14
15I also created this project as a way to learn Go. Although I'm satisfied with the results, it likely doesn't follow a lot of expected conventions.
16
17It is built around the [httpsig](https://github.com/common-fate/httpsig) library. This is the only library I found that implements the final RFC. Other libraries implement older drafts.
18
19# Try it out
20
21If you use Nix shell, there is a `shell.nix` config in the repo that should give you a working environment for running the project. If you can't/don't want to use Nix then the only requirements are Go and Caddy. (And possibly gcc, for the sqlite library. I have not tested this project on a system without gcc.)
22
23One program runs both the server and a test client.
24
25Run these commands in separate teminals to run the authentication server and a reverse proxy:
26
27```
28go run . -db register.db
29caddy run --config test_assets/Caddyfile
30```
31
32Then run these commands to register a key and make an authenticated request with it:
33
34```
35go run . -r -key test_assets/ed25519.pub -user test_user -base-url http://localhost:8080
36# Copy the key ID returned
37go run . -c -key test_assets/ed25519 -id <key_id>
38```
39
40If all is well you'll see the signing info on both client and server, see no errors, and get a response of "Hello, test_user"
41
42# Live use?
43
44This code is not ready for live use.
45
46I do not have much experience with crypto. Although I've tried to avoid mixing things and "rolling my own", I do not have the ability to evaluate and guarantee the safety of my code.
47
48These things would also need to be updated for me to be confident using it on a live server:
49
50There should be other database options besides sqlite.
51
52The registration flow needs better protection. The registration endpoint should not be open. The user should be authenticated through external means before trusting the key. Alternatively, with support for other databases, have the downstream service add keys to the database.
53
54The authority should be a configuration option, but I'm not likely to add that due to other restrictions that make this not work as general purpose middleware.
55
56The httpsig library isn't designed for this use. There are a few things that I think would have to be changed to make it fully functional.
57
581. There should be support for dynamic tags, which would be passed to the KeyDirectory.
59	1. This would be so the middleware could sit in front of multiple applications, each using its own tag.
602. It should be possible to allow multiple authorities.
613. If `content-digest` is in the covered components, there should be an option to use the `Content-Digest` header instead of recalcuating the digest itself.
62	1. In a middleware scenario, the authentication service doesn't have access to the body, so the calculated digest will be wrong.
63	2. Digest validation can be handled downstream.
64
65I also think the behavior of the `ForbidClientSideAlg` flag should be different, or there should be another option. If the flag is set, the verifier rejects signatures that include an algorithm. There should be an option where the client side algorithm is simply untrusted. In this mode:
66
674. The server must know the key algorithm through some other means. This project saves the algorithm with the key during registration.
685. If present, the client side algorithm is still compared to the known algorithm, as required by the RFC.
696. If not present, it doesn't matter.