frontier
frontier copied to clipboard
How to generate Bearer for API's
i've deployed the frontier on digitalocean kubernetes with spiceDB i've followed the raystack official helm charts and modify its values to setup.
But how can i setup server side secret key for JWT via helm values. I didnt see anywhere in docs.
i've generated key using frontier server keygen
locally. How can i do with configMaps or any other method. Also method to generate JWT for API communication.
eg : v1beta1/admin/users now i;m getting below error. as i'm not passing bearer token.
{"code":16, "message":"not authenticated", "details":[]}
Please guide
@kushsharma
@anishmenon JWT requires first setting up RSA keys for frontier, what you get using frontier server keygen
are the private RSA keys. We must pass these keys using a config map
to the frontier when it boots up. The reason it is not part of the chart is various people use various ways to pass it as a secure credential.
One easy way is to create a helm file templates/configmap-files.yaml
within frontier
charts directory and use
apiVersion: v1
kind: ConfigMap
metadata:
name: "{{ .Chart.Name }}-files"
namespace: "{{ include "app.namespace" . }}"
annotations:
"helm.sh/hook": pre-install,pre-upgrade
"helm.sh/hook-weight": "-5"
"helm.sh/resource-policy": "keep"
labels:
{{- include "app.labels" . | nindent 4 }}
data:
{{- if .Values.configPath }}
{{ (tpl (.Files.Glob (printf "%s" .Values.configPath) ).AsConfig . ) | indent 2 }}
{{- end }}
Create one more directory in frontier with the name files
and add the generated key in a file called rsa
and put it in this directory as ./files/rsa
In values.yaml
add a line at the top, this will ensure our config map reads all the files from files
directory and adds them as a key-value pair in the config map of kube.
configPath: "files/**"
So far we have put our RSA key in a config map but for frontier to find these keys we also need to mount it. Modify the frontier values.yaml
as follows
container:
command: ["frontier", "server", "start"]
ports:
- containerPort: 8080
protocol: TCP
- containerPort: 8081
protocol: TCP
volumeMounts:
- name: configs
mountPath: /etc/config
volumes:
- name: configs
configMap:
name: frontier-files
config:
FRONTIER_APP_AUTHENTICATION_TOKEN_RSA_PATH: /etc/config/rsa
Notice the newly added volumes
and additional env config.
But before you do all this, I would advise you to setup everything in your local machine using docker and test how it works. Let me know if you need help in setting up locally.
Here I want to use a presistance volume inorder to store the file or I need to build a docker image with the rsa key file and push to do docker hub.
To make it simple can I pass the raw json directly to configure map??
Like
key.json |
The chart takes care of the volume for you, no need to build the docker image with rsa key. Your rsa key must be kept as secure as possible, never put it in docker, never put it in git repo.
There is another(easier way) to pass the RSA private keys using base64
encoded string, just ensure you don't check in this string in your version control.
Run in shell to get base64 encoded keys
./frontier server keygen | base64
and put the string as
config:
FRONTIER_APP_AUTHENTICATION_TOKEN_RSA_BASE64: "......long string......."
Ensure you use dev
tag of the image as I just pushed this config a couple of minutes ago and it's not available on the latest release tag.
To verify if the RSA config is working, try hitting /.well-known/jwks.json
endpoint to see your public keys.
@kushsharma Thanks it is working.
Can you please explain the concept below example
- generate JWT using python /golang for Super admin with all permission scope to communicate with api
- generate JWT using python /golang for Organization SuperAdmin all permission scope of a spcefic org to communicate with api
@anishmenon we only support user account(human) for superuser at the moment(no serviceuser support for superusers). For example if a user login using mail otp or google, it can be uniquely identified by its email id. This email id can be added in admin config or via env as FRONTIER_APP_ADMIN_USERS="[email protected]". When the frontier boots up, it automatically make this account a superuser.
There is a workaround if you need temporary access to super user, you can exchange browser cookies with a jwt token via /v1beta1/auth/token
endpoint. The endpoint expects sid
cookie which is returned when we login/authenticate a user. This will give you a jwt
, pass this jwt
via Authorization: Bearer <jwt token>
and the request will work as super user.
Organization-level admins serviceusers can be created as follows:
- Create a service user under an organization
- Assign
app_organization_owner
role to this service user by creating a policy - Create a
key
credential of this service user - Use the
id
of key credential as username andsecret
as password in header likeAuthorization: Basic <base64 encoded id:secret>
private_key_dict = {"keys":[{"alg":"RS256","d":"o_9rp3y5gk_bj2edHFFBh3sgcJtKD750e5tidgjoj9RTe_in7USa_CGW2SXjM89zxNY4cOHT6RfC2OdwMRdNAfP7iPfIcheamhxbWf6VgIJjZKgUiJwb6pLxPQ9ghOXIq4sOpFtEUnQQg513mhufGhV-KvQp5-DcIU5zihY0Suta0jjjFyivOiAzw02-3sLlKDC8tmIVb9ABbHDCtUq2rzzxxzXtFnwPoJ8WD-COjlNwvTS0j-nUjvpK-5dNG2eB2HARWup7VIv8vFqmKOqrE8OgmmsgGPSnUx0OyVaj4c9QdPCqAMnAaG1P6C3ho2SQUT1nmR5QANeEQfhbEqp3WQ","dp":"Jfoy4ncFPXPO1Ay2aB1MY-UX_V1H35AwJM_qGmRLgWqIjGVNYKI0kaeQs8_xwILuzh22Gi_CwT7_EQ7fcJzK8YNxrw2uIisuqJ7Xu7dq8RLfc0T4Av9ChB31ZvN4jOwB_SjaNmtv8hw1Rg5xp5knXvGfs3gojh2lcpZJQ8rjYwc","dq":"PZRxzYYa1TLrXTdUa_FNEnmQNdsBx1DTEn7JYI6tjH7mb8R4GtsTOve2a6X_tNbwEStzfxApRaU8kmIECw3-1rgWCi7B1Bu0E2RFsnjvhV0Zzd9Y8Y4GNCQbxyWDfGqZ_YREGzSQMErid_4suoqatkXAfGv9ZEg2ii9T-9uPvsk","e":"AQAB","kid":"w_ruI4UbhZMyxjrIxSFKCteXfCSzrNWBemDUHAwvtV4","kty":"RSA","n":"yZHygO5LIfvoqb58jNF9rC90K9K_eSYd-npj5hIrloiRr7KCdJVG_1-yFN6BHCliMFtSwJ8wfacwU4zf6DjzhLFq8wTydw7kPlA7y3JdZX15_xXTppFosQVkB_kJT4gnEXXYGZboLitZXI0Ina8WgFsRlDnsuoHyZ3Aa7V2b6-XwgHG8M5CNpKgJlRZeTMooibWdNIL46mKAeuiuh6DliRHB6BW0VJyVtKkKwZBsCuDqVWDF9UIBO8P18CB2J9hYAVxSxlWyUxSFqfDFXTQOdmyayNdxuUe4nB_TskbNaZESzMQg-7f6xH5bUtIm8MsdnHbrs6TOYLjEpHIuTqADgw","p":"8GfgEacflpbkU6pOmnA5ZX37XNUUXw14EzCP3roksBuLjuT3tv7ExmnwmrV8gyttvX8tUoLUblOJNlLydibo1pd1ZFoJPoSberVbh2jVp5I5eCjU2a3-J5_mAnHhfxYnPwA0_zmMkAO-SCWT_jCv3J2HHIHEwrTX7E-Ez7Yxpmc","q":"1qUs_ESgmY2VF6VlpNqEOzyEVeBaOJ8r3DBqTSx_RGIuVErwOVZuzdpirU4CKaUrU4LowGkd5ayl_vIsIQgq-wCHGO1mukgqQBta2m38i7RJPOCWHEB65XsqVZPtnjbSY7Jb3uVjDSPYt6fV2x604ZbRAFxIqAm7ktQbDoIM8IU","qi":"Cq4ewNeymFibTVQLxSRpzKCPF699avAvM0djVZ9LG5wQcgO3Bay9klnRDm8nPUCgmbbnRFXI-cpAn98PSTC6U82ulq1t7SrCbUe2F-o580FGUaR9wwZlLGFO2KEw2uTMpi6TOFDvkek421t2D0L4x4xo_HWhxH96YZKAZWH2Mi8","use":"sig"},{"alg":"RS256","d":"M4BEQZaENKQDbXZaqa_E8njFN-s-ZqImI1H6uAlwOczcZOaWz6OOYgPY4VThu8u2HmNEtbof2zshnbMIrO6INasjfAavMl1wGkolmhuVhfdk6rvqAQIbOYcboZUTDwT6uOwlYh_fA49Khc0L43xRWrs6wUPTjDIfLkVV7dv3St8rKM-w94WCjbOcF73hXK2SkH8Lgjtak-uA-f4PPArnoFC96fKm1wPAMX7EncBIW3Yr81bXp4C9ObHR_s31CWjynpwt_8M3k9uNzUc5vyZYDPNe7BA35fCNzmODpGjPDP3bxFLUYVA9HKx7Y9u8KwO_rlaX-zKRrb-hE7xOrTQNOQ","dp":"LBuiHT3_4VS9Kgs2X1_pMkTOMVH7YSiUucDVITCuGP9ce9YQKXG-71Vsn8U93eGDOhqqNwzClNWKrIKzU12rV_-0E6wJ4el5oPpXUsLlv_9t3WrW1byiDPQ7M9oeZOTLHLSKg8XZ1qSnWwkwPqXrjsrlZpFubNqcF0kh3eXiEeU","dq":"DlVBfArJjb8ephF3lMZjh5KDA_N4sLTjVRS2maoJqkm_BBPWDBGIRfxvGcdRLPMZR4_DKeJlB5g9Xp4N-g4k25FuDKCwc_1dySaYVU908QuUQQ04AqVrTC0qvrywOlNGxxLpgbZS2FWYIkTQsRbPDg7C5G9Q8Fl5n5G14MWbxhc","e":"AQAB","kid":"Y6dFyZbPWwpoOPV77AdREAnLZDWpQhcZpAdmNQ9fMi4","kty":"RSA","n":"xPSRhzCAhIl-kMey6xPkfKwGwzFJZAVjrR-QxMV9dOEvVhra4aK5h2udbIYxZYc8hGASD30aap2NrHGv5ktG4skeU9ZHwANiERfii5KV2w5W0vkYMvi6fGmK3PM1E-I1emdRnNt-FjuirlM7elV9g3O4bCISX-ZbOE-JBKyWBjpnaOi551mPClIj_pfWSQHKxupIsKPPNGpIpoGCTGukPuzH-sUI6QCEZABQJGLuzHf6WW16hLp71Av_YaagG76BDmF2zj2y5DV0-QWeBWPGZtfqOq4lkAq2OOeyjqLMF56o8JDcCeDqH8rGpwi-f-GGqx0ouIyGh8YiAEhQk-Zbnw","p":"1IE30ODgA2YuAmDaM_JisTQLVOXCmFLD9CKukaiNQI8hY6itlKcMRZAsqXwbYm63aAzg4t38h5O93qPp6ETHhE0V6a6xIIbQOeNJjE14XeSr8yQLOikimd9ewdOqipu2LlOoAam5gwxwiLbV5eG-CF1FwNuaaxoLg_c21xnM_s0","q":"7USYbfG_gEUV3kDmFfvAf6WjsQN39gPAwf3H5aipcAXGTzPNjo3kbCl0V5SXljq6h7rbkm7DBbUuzn7oJYMhaXvN9GiQoUHgel3bZQ3rNgbwMsp2lTRwGWC6_6PaboqUOtK1e_KWD2sMFUVQ4xA9Wzoxes7hZJPRQGz8WGztbBs","qi":"qWCN84ko3EVjkS8gc2UGfVd_0F7VsimTyffKuzki8Mi1kmx-iUdo0vavioOqMhB2CbDPWCKoDzp4Ia3K8f9ufqhGv96rWtEnvGK2ER52UmhwsP5a94aPq0khsDJyr5dyRvBhAbW7IjnBGGNdosN-t2XRqxtGOna-d_JWho2VmXM","use":"sig"}]}
prv_first_key_dict = private_key_dict['keys'][0]
your_rsa_private_key = dict_to_private_key(prv_first_key_dict)
# Create Payload
payload = {
"sub": "1234567890",
"name": "John Doe",
"email": "[email protected]", // which is added in admin users
"iat": 1516239022,
"iss": "https://example.com",
}
encoded_jwt = jwt.encode(payload, your_rsa_private_key, algorithm='RS256')
print(encoded_jwt)
I tried pyJWT and generated JWT i tried communicating with below api give authentication 401Unauthorized error
`curl -L -X POST 'https://myservice.com/v1beta1/organizations'
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer JWT GENERATED'
--data-raw '{
"name": "DEMOOO",
"title": "Demo Org",
"metadata": {},
"avatar": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAA"
}'
@kushsharma
You don't create jwt using the private keys, they are only for frontier, otherwise all of your microservices that wants to communicate would require these private keys. Private keys should be kept as safe as possible.
To create a jwt, frontier provides an endpoint /v1beta1/auth/token
. Go through the authn part of docs for more information. Essentially follow these steps one to one maybe via postman/curl if that makes it easy. You can import swagger openapi spec from proto directory.
- Create a service user under an organization
- Assign app_organization_owner role to this service user by creating a policy
- Create a key credential of this service user
- Use the id of key credential as username and secret as password in header like Authorization: Basic
There is also an example provided for browser based logins under examples/authn/main.go
. Run it via go run main.go -frontierhost http://localhost:7400
once you have configured oidc
or mailer
configuration of frontier.
Hi @kushsharma i am having difficulty while accessing the admin portal in ui and as well via api. so i am using docker container with below runtime config
frontier:
image: raystack/frontier:latest
ports:
- "8081:8080"
command: server start
restart: on-failure
volumes:
- ./rsa:/opt/rsa
depends_on:
pg:
condition: service_healthy
environment:
- FRONTIER_DB_DRIVER=postgres
- FRONTIER_DB_URL=postgres://frontier:@pg:5432/frontier?sslmode=disable
- FRONTIER_SPICEDB_PORT=50051
- FRONTIER_SPICEDB_HOST=spicedb
- FRONTIER_SPICEDB_PRE_SHARED_KEY=frontier
- FRONTIER_APP_RESOURCES_CONFIG_PATH=file:///opt
- FRONTIER_APP_ADMIN_USERS="[email protected]"
- FRONTIER_APP_AUTHENTICATION_TOKEN_RSA_PATH=/opt/rsa
I have generated RSA:
frontier server keygen
Also i am using [email protected] to login i can see logout button but unauthorised acces
I have used localhost:8081/v1beta1/auth/token api by sending sid cookie (grab from ui ) and i was successfully able to get the jwt token.
next step i have used admin api its not getting authenticated. let me know if i am doing something wrong here. Also consider i didn't seed anything into database
its working i just needed to remove quote ;-)