I’ve recently started having more to do with Kubernetes lately, and have as a result have learned about the Sidecar Pattern.
I thought that maybe I should see if I can do something that might be useful for that, and one of the stinging points I’ve had is authentication.
Enter Peeper
Peeper was written to abstract away authentication from REST clients and presenting an interface that makes it look like they’re being presented with an unauthenticated interface. This may save some work if you’re writing services in multiple languages and don’t want to rewrite the authentication logic every time.
Architecture
Peeper sits on the edge of a network and proxies requests out to the protected services. At this point, it supports OAuth client credentials, static header keys and basic HTTP auth, with mTLS to come soon.
This begins when the client’s request first hits our locally configured endpoint. It is copied,
modified with the new URL, and passed into an interface I’ve named CredentialInjector
, whose job
it is to set the credentials correctly
type CredentialInjector interface {
InjectCredentials(req *http.Request) error
}
The injector can set headers, modify the body, etc.
This will also be augmented with an endpoint HTTP client config which will be able to configure mTLS certificates or route through other proxies.
Configuration
I wanted something simple-ish, so I chose TOML as my configuration format. I’ve used it in the past in production systems and it’s been powerful while also clearer than YAML or JSON.
The endpoint configuration looks a little like this
[endpoints]
[endpoints.cats]
local_path = "/cats"
remote_path = "https://cat-fact.herokuapp.com/facts"
local_method = "GET"
remote_method = "GET"
[endpoints.cats.basic_auth]
username = foo
password = bar
Where local_*
configures Peeper’s endpoints and remote_*
tell’s Peeper where to forward
any traffic coming into that endpoint.
Each endpoint also has three possible fields for authentication, basic_auth
, oauth
or
static_key
. Check the README
for more info on configuring these.
Security implications
I still have a few reservations about using this, and would probably only be comfortable using it in a heavily locked down network with proper firewall rules to make sure only the relevant services could hit it. This could also be augmented with added mTLS authentication.
Further plans
I’m hoping to set this up to being able to do mTLS, and maybe do some more restructuring of the code to allow better logging.
It would also be interesting to maybe be able to log out accesses and emit metrics, but that’s not really a priority for now.