Hi all,
I’ve read through man . And did not figure out if it is possible to use authentication mechanism to deny api requests without valid token in http header.
For example, I want to get a key by requesting /kv/:key
(as it stipulated in the man) But how can I filter such kind of requests for those only who gives valid jet? Or maybe it needs to put private keys on server side and validate these requests with the keys. What is the good practice to protect key-value consul storage?
Hi @rituzy,
Have a look at the Consul ACLs. Using ACLs you will be able to set permissions against Consul KV entries. Sharing some links to the documentation below.
- Secure Consul with Access Control Lists (ACLs) | Consul - HashiCorp Learn
- ACL Rules | Consul by HashiCorp - KV ACL rules
- ACL Rules | Consul by HashiCorp - Key Prefix resource
Hi @Ranjandas
Thank you for prompt reply. But all these documentations are about ACL. But what if I want to authenticate with keycloack server or validate JWT token came with incoming request? Maybe there is a way to use JWT authentication through ACL mechanism?
@rituzy, Yes you can authenticate external users using Consul Auth Methods and the users can be mapped to custom ACL roles using binding rules. - ACL Auth Methods | Consul by HashiCorp
This guide shows how OIDC is configured with Auth0 as the backend - Authenticate Users with Single Sign-On (SSO) and Auth0 | Consul - HashiCorp Learn.
Please note that the OIDC auth-method type is an Enterprise feature.
Hi @rituzy,
As @Ranjandas mentioned, Consul’s ACL system is the appropriate way to secure access to resources like KV entries, services, etc.
Consul’s JWT auth method allows a user to authenticate with Consul using a valid JWT and obtain an ACL token based on information contained within the JWT claims. The permissions granted to this token are defined by the operator via ACL binding rules.
Its important to note that this authentication via JWT should only happen for the initial login. All subsequent API requests from the client should utilize the issued ACL token until it expires, at which point the client and login again using another valid JWT so that they can obtain an updated ACL token.
Hi @Blake ,
thanks for you reply. Let me sum up this info and show the example.
Purpose : client wants to get data from consul storage.
-
Client sends PUT request to consul
<consul-address>/acl/auth-method
with payload :
{
“Name”: “client-name”,
“Type”: “jet”,
“Description”: “client connection”,
“Config”: {
" JWKSURL": “https://my-corp-jwks-url.example.com/”
}
} -
Client gets response with token (JWT or ACL token?)
-
Client gets data with this token in http header :
GET
request<consul-address>/kv/:key
(Prior it needs to add role, identity and bind them with binding.) -
Client sends request logout requuest:
DELETE
<consul-address>/acl/auth-method/:name
with this token to make this token invalid
Is this algorithm correct or maybe we need to take something else into the picture?
And how this interaction with JWKSURL is set? At which step we use our keyclock auth provider here?
P.S. and it’s not clear for me, what I reached by auth-method PUT
method (from here) What should I use to get key-value data with all this staff in reply
{
"Name": "client-name",
"Type": "jwt",
"Description": "client connection",
"Config": {
"JWKSURL": "https://my-corp-jwks-url.example.com/"
},
"CreateIndex": 130123,
"ModifyIndex": 130123
}
Hi @rituzy,
This auth method should be pre-created by the cluster operator.
{
“Name”: “jwt-auth-method”,
“Type”: “jwt”,
“Description”: “Auth method for logging into Consul using JWT tokens”,
“Config”: {
"JWKSURL": “https://my-corp-jwks-url.example.com/”
}
}
It will be referenced by clients when they send a POST request to /v1/acl/login
in order to login to the API using the auth method.
{
"AuthMethod": "jwt-auth-method",
"BearerToken": "<jwt token>"
}
The client would receive a Consul ACL token in the response. See the auth method login sample response for an example of this output.
The client then provides the SecretID in the X-Consul-Token
or Authorization
header when making requests to Consul. See HTTP API authentication for more detail.
When the client is ready to logout, it can send a POST request to /v1/acl/logout
in order to destroy the API token.
If you want to obtain KV data, you will need to use the /v1/kv
API endpoint.
I hope this helps. Let me know if you have any additional questions.
Hi @blake,
thank you so much for such a big explanation with quick example. But I failed to pass second step with calling /v1/acl/login
method
I send this put request /v1/acl/auth-method
{
"Name": "ja9",
"Type": "jwt",
"Description": "client connection",
"Config": {
"JWKSURL": "https://my-corp-jwks-url.example.com/protocol/openid-connect/certs",
"BoundAudiences": [
"acc"
]
}
}
(I need to put BoundAudiences as JWT contains thisaud
claim. Otherwise on the next step(see below) consul complains that aud
is found in the token and neither audience names were given to consul)
I receive success result of creating the method
{
"Name": "ja9",
"Type": "jwt",
"Description": "client connection",
"Config": {
"BoundAudiences": [
"account"
],
"JWKSURL": "https://my-corp-jwks-url.example.com/protocol/openid-connect/certs"
},
"CreateIndex": 153540,
"ModifyIndex": 153540
}
then on the step 2 I send a post request /v1/acl/login
:
{
"AuthMethod": "ja9",
"BearerToken": "<long string token goes here>"
}
and receive response with 403 code
rpc error making call: Permission denied
Consul logs do not provide any more information about this error(only this string “Permition denied”)
If I try to decode the token I would find the KID field which can be met in the JWKS page. (that says that token is issued by correct issuer)
As a workaround for this problem I thought about placing RSA key in auth-method call. But I do have x5c field (this seems to be the same open part of the key but of cause not RSA with content like “===BEGIIN CERTIFICATE…”) And while trying to create auth method v1/acl/auth-method
:
{
"Name": "ja10",
"Type": "jwt",
"Description": "client connection",
"Config": {
"JWTValidationPubKeys": [
"<x5c field from jwks page goes here>"
],
"BoundAudiences": [
"acc"
]
}
}
consul responses:
rpc error making call: Invalid Auth Method: error parsing public key JWTValidationPubKeys[0]: data does not contain any valid RSA, ECDSA, or ED25519 public keys
Could you please help me to make my way further as per your instructions above?
Thank you in advance!
bump!
Btw could you please advise how can I get verbose security logs for authentication process?
The things needs to do for working process are:
- create policy for accessing kv storage
- create role and link to the policy above
- create acl binding-rule to auth method created earlier(see previous replies here)
Than it will be working as described earlier.
Thanks guys, the topic is closed.