diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index cafb439..940546c 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -32,4 +32,4 @@ jobs: echo "changed=true" >> "$GITHUB_OUTPUT" fi - if: steps.list-changed.outputs.changed == 'true' - run: ct lint --chart-repos cluster=https://cloudnative-pg.io/charts + run: ct lint --chart-repos cluster=https://cloudnative-pg.io/charts --chart-repos ingress-nginx=https://kubernetes.github.io/ingress-nginx diff --git a/charts/postgrest/Chart.lock b/charts/postgrest/Chart.lock index 008b4b0..7f54daf 100644 --- a/charts/postgrest/Chart.lock +++ b/charts/postgrest/Chart.lock @@ -2,5 +2,8 @@ dependencies: - name: cluster repository: https://cloudnative-pg.io/charts version: 0.5.0 -digest: sha256:bd4115e6b9154294c12879f19116e015f1e98563d7f1324f103ed170e3dab69e -generated: "2026-01-08T14:31:47.621461-05:00" +- name: ingress-nginx + repository: https://kubernetes.github.io/ingress-nginx + version: 4.14.1 +digest: sha256:abf4abe5cb6b67c3f6a9b102e94cefa9e9bc5431417756ebb8cf6f36d9847bc1 +generated: "2026-01-26T10:40:50.598179-06:00" diff --git a/charts/postgrest/Chart.yaml b/charts/postgrest/Chart.yaml index 1f3298d..bdd58e5 100644 --- a/charts/postgrest/Chart.yaml +++ b/charts/postgrest/Chart.yaml @@ -1,7 +1,7 @@ apiVersion: v2 name: postgrest icon: https://docs.postgrest.org/en/v14/_images/postgrest.png -version: 0.3.0 +version: 0.4.0 maintainers: - name: jared-prime email: jared.davis@pelo.tech @@ -12,3 +12,7 @@ dependencies: version: 0.5.0 repository: https://cloudnative-pg.io/charts condition: cluster.enabled + - name: ingress-nginx + version: 4.14.1 + repository: https://kubernetes.github.io/ingress-nginx + condition: ingress.enabled diff --git a/charts/postgrest/keyserver/main.ts b/charts/postgrest/keyserver/main.ts index 342764f..e289ded 100644 --- a/charts/postgrest/keyserver/main.ts +++ b/charts/postgrest/keyserver/main.ts @@ -11,11 +11,13 @@ const origin = Deno.env.get('PGRST_CLIENT_ORIGIN')?.split(',') ?? []; const trusted = Deno.env.get('PGRST_JWK_TRUST')?.split(',') ?? []; const cert = Deno.env.get('PGRST_JWK_CERT') ?? 'cert.pem'; const alg = Deno.env.get('PGRST_JWT_ALG') ?? 'RS256'; -const iss = Deno.env.get('PGRST_JWT_ISS') ?? 'http://localhost:8000/jwks' +const iss = Deno.env.get('PGRST_JWT_ISS') ?? 'http://localhost:8000' const aud = Deno.env.get('PGRST_JWT_AUD') ?? 'postgrest'; const exp = Deno.env.get('PGRST_JWT_EXP') ?? '5 minutes'; const sub = Deno.env.get('PGRST_JWT_SUB') ?? 'anon'; const api = Deno.env.get('PGRST_CLIENT_KEY') ?? ''; +const typ = 'JWT'; +const jwks_uri = Deno.env.get('PGRST_JWKS_URI') ?? 'http://localhost:8000/jwks' let keypair: GenerateKeyPairResult; const initialize = async () => { @@ -26,7 +28,7 @@ const initialize = async () => { await write(keysets); localStorage.setItem('jwk:kid', keysets.keys[0].kid); - localStorage.setItem('jwk:val', JSON.stringify(keysets.keys[0])) + localStorage.setItem('jwk:set', JSON.stringify(keysets)) } const upstream = async (): Promise> => { @@ -43,14 +45,12 @@ const upstream = async (): Promise> => { for await (const address of trusted) { try { const response = await fetch(address, { client }) - console.log(response.status) const data = await response.json() as JSONWebKeySet; keyset.push(...data.keys) } catch (error) { console.warn(error) } } - console.debug(keyset); return keyset; } @@ -64,7 +64,7 @@ const jwk = async (key: CryptoKey, ...jwks: Array): Promise } const jwt = async (key: CryptoKey, kid?: string): Promise => await new SignJWT(claims) - .setProtectedHeader({ alg, kid }) + .setProtectedHeader({ alg, kid, typ }) .setAudience(aud) .setIssuedAt() .setExpirationTime(exp) @@ -83,18 +83,22 @@ const write = async (keys: JSONWebKeySet) => { const app = new Hono(); -app.use('/jwks/.well-known/openid-configuration', cors({ origin })) -app.get('/jwks/.well-known/openid-configuration', (context) => { - const keyset = localStorage.getItem('jwk:val'); +app.use('/', cors({ origin })) +app.get('/', (context) => context.redirect('/.well-known/openid-configuration', 301)); + +app.use('/.well-known/openid-configuration', cors({ origin })) +app.get('/.well-known/openid-configuration', (context) => context.json({jwks_uri})) + +app.use('/jwks', cors({ origin })) +app.get('/jwks', (context) => { + const keyset = localStorage.getItem('jwk:set'); if (keyset) return context.json(JSON.parse(keyset)); return context.json({message:'not found'}, 404); }); -app.get('/', (context) => context.redirect('/jwks/.well-known/openid-configuration', 301)); -app.get('/jwks', (context) => context.redirect('/jwks/.well-known/openid-configuration', 301)); - +app.use('/peek', cors({ origin })) app.get('/peek', async (context) => { const auth = context.req.header('Authorization')?.replace('Bearer ', ''); diff --git a/charts/postgrest/templates/ingress.yaml b/charts/postgrest/templates/ingress.yaml new file mode 100644 index 0000000..4ac0c92 --- /dev/null +++ b/charts/postgrest/templates/ingress.yaml @@ -0,0 +1,18 @@ +{{- if .Values.ingress.enabled }} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: postgrest-ingress + labels: + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/part-of: ingress-nginx + annotations: + nginx.ingress.kubernetes.io/enable-cors: "true" + nginx.ingress.kubernetes.io/use-regex: "true" +spec: + ingressClassName: "nginx" + tls: + {{- .Values.ingress.tls | toYaml | nindent 4 }} + rules: + {{- .Values.ingress.rules | toYaml | nindent 4 }} +{{- end }} \ No newline at end of file diff --git a/charts/postgrest/values.yaml b/charts/postgrest/values.yaml index 9b0841f..aa03507 100644 --- a/charts/postgrest/values.yaml +++ b/charts/postgrest/values.yaml @@ -86,11 +86,41 @@ keyserver: key: a-string-secret-at-least-256-bits-long jwt: alg: RS256 - iss: https://localhost:8000/jwks + iss: https://auth.app.localhost aud: postgrest exp: 5 minutes claims: postgrest: role: peek - origin: https://jwt.io,https://example.com - trust: https://keycloak/auth/realms/od360-kind/protocol/openid-connect/certs + origin: https://jwt.io,https://app.localhost + trust: https://sso.localhost/auth/realms/example/protocol/openid-connect/certs + jwks_uri: https://auth.app.localhost/jwks + +ingress: + enabled: true + tls: + - hosts: + - 'auth.app.localhost' + - 'data.app.localhost' + secretName: 'app.localhost-tls' + rules: + - host: 'auth.app.localhost' + http: + paths: + - pathType: Prefix + path: / + backend: + service: + name: postgrest + port: + name: keyserver + - host: 'data.app.localhost' + http: + paths: + - pathType: Prefix + path: / + backend: + service: + name: postgrest + port: + name: postgrest