-
Notifications
You must be signed in to change notification settings - Fork 32
add helm chart for MAS deployments #2653
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Patterns to ignore when building packages. | ||
# This supports shell glob matching, relative path matching, and | ||
# negation (prefixed with !). Only one pattern per line. | ||
.DS_Store | ||
# Common VCS dirs | ||
.git/ | ||
.gitignore | ||
.bzr/ | ||
.bzrignore | ||
.hg/ | ||
.hgignore | ||
.svn/ | ||
# Common backup files | ||
*.swp | ||
*.bak | ||
*.tmp | ||
*.orig | ||
*~ | ||
# Various IDEs | ||
.project | ||
.idea/ | ||
*.tmproj | ||
.vscode/ | ||
*conf.yaml |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
apiVersion: v2 | ||
name: mas | ||
description: A Helm chart for matrix-authentication-service | ||
type: application | ||
version: 0.1.1 | ||
appVersion: "0.9.0" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# Oddities with MAS | ||
|
||
## general | ||
|
||
After initialising the pod you need to sync MAS with it's config | ||
|
||
```bash | ||
kubectl exec -it -n mas deployments/mas -- mas-cli config sync | ||
``` | ||
|
||
otherwise you'll run into issues with synapse reporting "*unable to introspect token*" and MAS complaining about not knowing about the configured `client_id`s | ||
|
||
## migrating users from synapse db to mas | ||
|
||
you need to run the tool `syn2mas` which isn't at all included in the mas itself. | ||
While an container exits for it it's still quite difficult to use. | ||
|
||
- You're much quicker by spawning up a container such as | ||
```bash | ||
kubectl run -i --tty --rm debug --image=node:lts --restart=Never -- bash | ||
``` | ||
- add your homeserver.yaml and mas config.yaml | ||
- install the `syn2mas` | ||
```bash | ||
npx @matrix-org/syn2mas | ||
``` | ||
- run preadvisor **or** | ||
```bash | ||
npx @matrix-org/syn2mas --command=advisor --synapseConfigFile homeserver.yaml | ||
``` | ||
- run migration | ||
```bash | ||
npx @matrix-org/syn2mas --command=migrate --synapseConfigFile homeserver.yaml --masConfigFile config.yaml | ||
``` | ||
|
||
## troubleshooting | ||
|
||
mas offers a diagnostic tool which is rather help full, you can run it with | ||
```bash | ||
kubectl exec -it -n mas deployments/mas -- mas-cli doctor | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,281 @@ | ||
http: | ||
# Public URL base used when building absolute public URLs | ||
public_base: "{{ .Values.config.http.public_base -}}/" | ||
|
||
# OIDC issuer advertised by the service. Defaults to `public_base` | ||
issuer: {{ .Values.config.http.issuer | default .Values.config.http.public_base | quote }} | ||
|
||
# Each listener can serve multiple resources, and listen on multiple TCP ports or UNIX sockets. | ||
# List of HTTP listeners, see below | ||
listeners: | ||
# The name of the listener, used in logs and metrics | ||
- name: web | ||
|
||
# List of resources to serve | ||
resources: {{- range .Values.config.listeners.resources }} | ||
- name: {{ .name }} | ||
{{- if .path }} | ||
path: {{ .path -}} | ||
{{- end }} | ||
{{- if .playground }} | ||
playground: {{ .playground }} | ||
{{- end }} | ||
{{- end }} | ||
Comment on lines
+15
to
+23
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If anyway the chart exposes everything on a single port (which is fine!), I wouldn't expose the various resources in the values, but rather flags like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. which listener make sense to expose by default and which should always be optional besides |
||
- name: health | ||
path: /health | ||
{{- if .Values.telemetry.metrics.enabled }} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what is the idea behind putting some config values below |
||
- name: prometheus | ||
path: /health | ||
{{- end }} | ||
|
||
binds: | ||
- address: '[::]:8080' | ||
proxy_protocol: {{ .Values.config.listeners.proxy_protocol }} | ||
trusted_proxies: {{ range .Values.config.trusted_proxies }} | ||
- {{ . }} | ||
{{- end }} | ||
|
||
# Configure how to connect to the PostgreSQL database. | ||
database: | ||
# Full connection string as per | ||
# https://www.postgresql.org/docs/13/libpq-connect.html#id-1.7.3.8.3.6 | ||
#uri: postgresql://user:password@hostname:5432/database?sslmode=require | ||
|
||
# -- OR -- | ||
# Separate parameters | ||
host: {{ .Values.database.host }} | ||
port: {{ .Values.database.port }} | ||
#socket: | ||
username: {{ .Values.database.username }} | ||
password: {{ .Values.database.password }} | ||
database: {{ .Values.database.dbName }} | ||
|
||
# Additional parameters for the connection pool | ||
min_connections: {{ .Values.database.min_connections }} | ||
max_connections: {{ .Values.database.max_connections }} | ||
connect_timeout: {{ .Values.database.connect_timeout }} | ||
idle_timeout: {{ .Values.database.idle_timeout }} | ||
max_lifetime: {{ .Values.database.max_lifetime }} | ||
|
||
# Settings related to the connection to the Matrix homeserver | ||
matrix: | ||
# The homeserver name, as per the `server_name` in the Synapse configuration file | ||
homeserver: {{ .Values.matrix.homeserver }} | ||
|
||
# Shared secret used to authenticate the service to the homeserver | ||
# This must be of high entropy, because leaking this secret would allow anyone to perform admin actions on the homeserver | ||
secret: {{ .Values.matrix.sharedSecret | quote }} | ||
|
||
# URL to which the homeserver is accessible from the service | ||
endpoint: {{ .Values.matrix.homeserverUrl | quote }} | ||
|
||
# Allows loading custom templates | ||
{{- if .Values.templates.enabled }} | ||
templates: | ||
path: {{ .Values.templates.path }} | ||
assets_manifest: {{ .Values.templates.assets }} | ||
{{- end }} | ||
|
||
# List of OAuth 2.0/OIDC clients and their keys/secrets. Each client_id must be a ULID. | ||
clients: | ||
# Confidential client | ||
- client_id: {{ .Values.clients.client_id }} | ||
client_auth_method: {{ .Values.clients.client_auth_method }} | ||
client_secret: {{ .Values.clients.client_secret }} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i understand that secrets handling mostly depends on custom integrations, but having secrets in a configmap is not so typical. anance's synapse chart for instance puts them into separate config files from secrets. it has pros and cons. |
||
# List of authorized redirect URIs | ||
redirect_uris: {{ .Values.clients.redirect_uris}} | ||
# Public client | ||
- client_id: {{ .Values.clients.pub_id }} | ||
client_auth_method: {{ .Values.clients.pubAuthMethod }} | ||
|
||
# Signing and encryption secrets | ||
secrets: | ||
encryption: {{ randAlphaNum 32 | printf "%x" }} | ||
|
||
# Signing keys | ||
keys: | ||
- kid: {{ randAlphaNum 10 }} | ||
key: | | ||
{{- genPrivateKey "rsa" | nindent 10 }} | ||
- kid: {{ randAlphaNum 10 }} | ||
key: | | ||
{{- genPrivateKey "ecdsa" | nindent 10 }} | ||
- kid: {{ randAlphaNum 10 }} | ||
key: | | ||
{{- genPrivateKey "ecdsa" | nindent 10 }} | ||
- kid: {{ randAlphaNum 10 }} | ||
key: | | ||
{{- genPrivateKey "ecdsa" | nindent 10 }} | ||
|
||
|
||
passwords: | ||
# Whether to enable the password database. | ||
# If disabled, users will only be able to log in using upstream OIDC providers | ||
enabled: {{ .Values.passwords.enabled }} | ||
|
||
# List of password hashing schemes being used | ||
# /!\ Only change this if you know what you're doing | ||
schemes: {{- range .Values.passwords.schemes }} | ||
- version: {{ .version }} | ||
algorithm: {{ .algorithm }} | ||
{{- end}} | ||
policy: | ||
data: | ||
admin_users: {{ .Values.policy.data.admins }} | ||
|
||
# Dynamic Client Registration | ||
client_registration: | ||
# don't require URIs to be on the same host. default: false | ||
allow_host_mismatch: {{ .Values.policy.data.clientHostMismatch | default "false" }} | ||
# allow non-SSL and localhost URIs. default: false | ||
allow_insecure_uris: {{ .Values.policy.data.clientNoSsl | default "false" }} | ||
|
||
# Registration using passwords | ||
passwords: | ||
# minimum length of a password. default: ? | ||
min_length: {{ .Values.policy.data.pass.minLength }} | ||
# require at least one lowercase character in a password. default: false | ||
require_lowercase: {{ .Values.policy.data.pass.reqLowCase }} | ||
# require at least one uppercase character in a password. default: false | ||
require_uppercase: {{ .Values.policy.data.pass.reqUpCase }} | ||
# require at least one number in a password. default: false | ||
require_number: {{ .Values.policy.data.pass.reqNum }} | ||
{{- if .Values.telemetry.enabled }} | ||
telemetry: | ||
tracing: | ||
# List of propagators to use for extracting and injecting trace contexts | ||
propagators: {{ .Values.telemetry.propagators }} | ||
|
||
# The default: don't export traces | ||
exporter: {{ .Values.telemetry.exporter }} | ||
{{- if .Values.telemetry.useOTLP.enabled }} | ||
endpoint: {{ .Values.telemetry.useOTLP.endpoint }} | ||
{{- end }} | ||
{{- if .Values.telemetry.metrics.enabled}} | ||
metrics: | ||
exporter: {{ .Values.telemetry.metrics.exporter }} | ||
endpoint: {{ .Values.telemetry.metrics.enpoint }} | ||
{{- end }} | ||
{{- if .Values.telemetry.sentry.enabled}} | ||
sentry: | ||
dsn: {{ .Values.telemetry.sentry.dsn }} | ||
{{- end }} | ||
{{- end }} | ||
|
||
email: | ||
from: {{ .Values.email.from | squote }} | ||
reply_to: {{ .Values.email.reply2 | squote }} | ||
transport: {{ .Values.email.transport }} | ||
{{- if .Values.email.enabled }} | ||
hostanme: {{ .Values.email.hostname }} | ||
mode: {{ .Values.email.mode }} | ||
port: {{ .Values.email.port }} | ||
username: {{ .Values.email.username }} | ||
password: {{ .Values.email.password }} | ||
{{- end }} | ||
|
||
# Sample configurations for popular providers can be found in the upstream provider setup guide. | ||
# https://matrix-org.github.io/matrix-authentication-service/setup/sso.html#sample-configurations | ||
upstream_oauth2: | ||
providers: [] | ||
{{- if .Values.upstream_oauth2.enabled }} | ||
- id: {{ .Values.upstream_oauth2.providerId }} | ||
|
||
# The issuer URL, which will be used to discover the provider's configuration. | ||
# If discovery is enabled, this *must* exactly match the `issuer` field | ||
# advertised in `<issuer>/.well-known/openid-configuration`. | ||
issuer: {{ .Values.upstream_oauth2.issuerUrl }} | ||
|
||
human_name: {{ .Values.upstream_oauth2.humanName }} | ||
|
||
# A brand identifier for the provider, which will be used to display a logo | ||
# on the login page. Values supported by the default template are: | ||
# - `apple` | ||
# - `google` | ||
# - `facebook` | ||
# - `github` | ||
# - `gitlab` | ||
# - `twitter` | ||
brand_name: {{ .Values.upstream_oauth2.brand }} | ||
|
||
# The client ID to use to authenticate to the provider | ||
client_id: {{ .Values.upstream_oauth2.clientId }} | ||
|
||
# The client secret to use to authenticate to the provider | ||
# This is only used by the `client_secret_post`, `client_secret_basic` | ||
# and `client_secret_jwk` authentication methods | ||
client_secret: {{ .Values.upstream_oauth2.client_secret }} | ||
|
||
# Which authentication method to use to authenticate to the provider | ||
# Supported methods are: | ||
# - `none` | ||
# - `client_secret_basic` | ||
# - `client_secret_post` | ||
# - `client_secret_jwt` | ||
# - `private_key_jwt` (using the keys defined in the `secrets.keys` section) | ||
token_endpoint_auth_method: {{ .Values.upstream_oauth2.endpointAuth }} | ||
{{- if .Values.upstream_oauth2.endpoint.useJwt }} | ||
token_endpoint_auth_signing_alg: {{ .Values.upstream_oauth2.endpointAuthSignAlg }} | ||
{{- end }} | ||
# The scopes to request from the provider | ||
# In most cases, it should always include `openid` scope | ||
scope: {{ .Values.upstream_oauth2.scope }} | ||
|
||
# How the provider configuration and endpoints should be discovered | ||
# Possible values are: | ||
# - `oidc`: discover the provider through OIDC discovery, | ||
# with strict metadata validation (default) | ||
# - `insecure`: discover through OIDC discovery, but skip metadata validation | ||
# - `disabled`: don't discover the provider and use the endpoints below | ||
discovery_mode: {{ .Values.upstream_oauth2.discovery_mode }} | ||
|
||
# Whether PKCE should be used during the authorization code flow. | ||
# Possible values are: | ||
# - `auto`: use PKCE if the provider supports it (default) | ||
# Determined through discovery, and disabled if discovery is disabled | ||
# - `always`: always use PKCE (with the S256 method) | ||
# - `never`: never use PKCE | ||
pkce_method: {{ .Values.upstream_oauth2.pkce }} | ||
|
||
# The provider authorization endpoint | ||
# This takes precedence over the discovery mechanism | ||
authorization_endpoint: {{ .Values.upstream_oauth2.authorization_endpoint }} | ||
|
||
# The provider token endpoint | ||
# This takes precedence over the discovery mechanism | ||
token_endpoint: {{ .Values.upstream_oauth2.token_endpoint }} | ||
|
||
# The provider JWKS URI | ||
# This takes precedence over the discovery mechanism | ||
jwks_uri: {{ .Values.upstream_oauth2.jwks_uri }} | ||
|
||
claims_imports: | ||
subject: | ||
{{- with .Values.upstream_oauth2.claims_imports.subject.template }} | ||
template: {{ . | quote }} | ||
{{- end }} | ||
localpart: | ||
{{- with .Values.upstream_oauth2.claims_imports.localpart.action }} | ||
action: {{ . }} | ||
{{- end }} | ||
{{- with .Values.upstream_oauth2.claims_imports.localpart.template }} | ||
template: {{ . | quote }} | ||
{{- end }} | ||
displayname: | ||
{{- with .Values.upstream_oauth2.claims_imports.displayname.action }} | ||
action: {{ . }} | ||
{{- end }} | ||
{{- with .Values.upstream_oauth2.claims_imports.displayname.template }} | ||
template: {{ . | quote }} | ||
{{- end }} | ||
email: | ||
{{- with .Values.upstream_oauth2.claims_imports.email.action }} | ||
action: {{ . }} | ||
{{- end }} | ||
{{- with .Values.upstream_oauth2.claims_imports.email.template }} | ||
template: {{ . | quote }} | ||
{{- end }} | ||
{{- with .Values.upstream_oauth2.claims_imports.email.set_email_verification }} | ||
set_email_verification: {{ . }} | ||
{{- end }} | ||
{{- end }} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
1. Get the application URL by running these commands: | ||
{{- if .Values.ingress.enabled }} | ||
{{- range $host := .Values.ingress.hosts }} | ||
{{- range .paths }} | ||
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} | ||
{{- end }} | ||
{{- end }} | ||
{{- else if contains "NodePort" .Values.service.type }} | ||
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "mas.fullname" . }}) | ||
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") | ||
echo http://$NODE_IP:$NODE_PORT | ||
{{- else if contains "LoadBalancer" .Values.service.type }} | ||
NOTE: It may take a few minutes for the LoadBalancer IP to be available. | ||
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "mas.fullname" . }}' | ||
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "mas.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") | ||
echo http://$SERVICE_IP:{{ .Values.service.port }} | ||
{{- else if contains "ClusterIP" .Values.service.type }} | ||
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "mas.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") | ||
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") | ||
echo "Visit http://127.0.0.1:8080 to use your application" | ||
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT | ||
{{- end }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the sync could be run from an init container. since the migrations and basic sync are now performed automatically on start up we added: