-
Notifications
You must be signed in to change notification settings - Fork 62
Authentication
Piko uses a JSON Web Token (JWT) provided by your application to authenticate connecting clients. To enable authentication, configure the Piko server with a secret key or public key to verify the client JWT. The JWT may also include Piko specific claims the server will verify, such as what endpoints the client is permitted to connect to or listen on.
Each server port has independent configuration, such as you may authenticate upstream listeners but not clients connecting to the proxy port.
Piko supports HMAC, RSA, and ECDSA JWT algorithms, specifically HS256, HS384, HS512, RSA256, RSA384, RSA512, EC256, EC384, and EC512.
Each port has configuration:
auth:
# Secret key to authenticate HMAC endpoint connection JWTs.
hmac_secret_key: ""
# Public key to authenticate RSA endpoint connection JWTs.
rsa_public_key: ""
# Public key to authenticate ECDSA endpoint connection JWTs.
ecdsa_public_key: ""
# Audience of endpoint connection JWT token to verify.
#
# If given the JWT 'aud' claim must match the given audience. Otherwise it
# is ignored.
audience: ""
# Issuer of endpoint connection JWT token to verify.
#
# If given the JWT 'iss' claim must match the given issuer. Otherwise it
# is ignored.
issuer: ""
Such as to configure the HMAC secret key for the 'upstream' port, configure upstream.auth.hmac-secret-key
.
If any of the secret key or public key options are configured, then clients must include a valid JWT that can be verified by one of those keys.
Piko will verify the exp
(expiry) and iat
(issued at) claims if included in the JWT.
You can also optionally configure the audience
and issuer
options, which Piko will use to verify the aud
and iss
JWT claims respectively. If empty Piko won't verify the claims.
Piko also supports JWTs with a configured set of endpoint IDs that the client can access using claim piko.endpoints
. When configured on the 'proxy' port, this is the list of endpoints the client can connect to, or when configured on the 'upstream' port it is the endpoints the upstream can listen on. Such as if the JWT includes claim "piko": {"endpoints": ["endpoint-123"]}
, it will be permitted to access
endpoint ID endpoint-123
only. If the piko.endpoints
claim is not included in the JWT, the client can access any endpoint.
This example shows you how to create a simple HS256 JWT using Python and use it to configure Piko clients and upstreams.
First create a HS256 JWT token in Python using a HMAC secret key my-secret
:
import jwt
token = jwt.encode({}, "my-secret")
print(token) # eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI0MiJ9.cYo84rqiyvYovXGPGxY7a4qWLa5HA857Nb2uMrkVcHs
As described above, you can also include Piko specific claims in the JWT payload. Such as to restrict the client to endpoint my-endpoint
only, use:
token = jwt.encode({"piko": {"endpoints": ["my-endpoint"]}}, "my-secret")
print(token) # eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJwaWtvIjp7ImVuZHBvaW50cyI6WyJteS1lbmRwb2ludCJdfX0.I7Vkc2w0-CuEUz-ePRBEFx_-9aCAOH6BN146BZBIxGw
Next start the Piko server and configure it to verify the client JWT using the HMAC secret. This example enables authentication on both the 'proxy' port and 'upstream port':
$ piko server --proxy.auth.hmac-secret-key my-secret --upstream.auth.hmac-secret-key my-secret
You can also configure the server using YAML configuration, such as:
# server.yaml
proxy:
auth:
hmac_secret_key: my-secret
upstream:
auth:
hmac_secret_key: my-secret
Then run the server with:
$ piko server --config.path ./server.yaml
HTTP clients connecting to the proxy port must then include either Authorization: Bearer <token>
or x-piko-authorization: Bearer <token>
, replacing the token with one of the JWT's created above, such as:
$ curl http://localhost:8000 \
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJwaWtvIjp7ImVuZHBvaW50cyI6WyJteS1lbmRwb2ludCJdfX0.I7Vkc2w0-CuEUz-ePRBEFx_-9aCAOH6BN146BZBIxGw" \
-H "x-piko-endpoint: my-endpoint"
Note Piko supports both Authorization
and x-piko-authorization
, since Authorization
may conflict with your upstream services Authorization
. Therefore if both are given x-piko-authorization
takes precedence.
When adding upstream listeners using piko agent
, to authenticate the agent you must configure --connect.token
to authenticate the agent with the server. Such as:
$ piko agent http my-endpoint 3000 --connect.token eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJwaWtvIjp7ImVuZHBvaW50cyI6WyJteS1lbmRwb2ludCJdfX0.I7Vkc2w0-CuEUz-ePRBEFx_-9aCAOH6BN146BZBIxGw
When connecting to Piko using piko forward
, to authenticate the forward client you must configure --connect.token
. Such as:
$ piko forward tcp 6000 my-endpoint --connect.token eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJwaWtvIjp7ImVuZHBvaW50cyI6WyJteS1lbmRwb2ludCJdfX0.I7Vkc2w0-CuEUz-ePRBEFx_-9aCAOH6BN146BZBIxGw
Note when using piko forward
you don't have to authenticate the client that connects to Piko via piko forward
.