Jelajahi Sumber

Helm chart SSO support (#17205)

* Add SAML support

* move extAuth below essential components

* Add CAS, PAM, LDAP support

* Add WEB_DOMAIN and S3_ALIAS_HOST support

* SAML defaults aligned

* Bump chart version

* SSO & WEB_DOMAIN support added

* Add OIDC support

* Correct typo

* Notice for OIDC support

Co-authored-by: Eugen Rochko <eugen@zeonfederated.com>
bobbyd0g 2 tahun lalu
induk
melakukan
a131f06e12
4 mengubah file dengan 329 tambahan dan 3 penghapusan
  1. 1 1
      chart/Chart.yaml
  2. 0 2
      chart/readme.md
  3. 224 0
      chart/templates/configmap-env.yaml
  4. 104 0
      chart/values.yaml

+ 1 - 1
chart/Chart.yaml

@@ -15,7 +15,7 @@ type: application
 # This is the chart version. This version number should be incremented each time you make changes
 # to the chart and its templates, including the app version.
 # Versions are expected to follow Semantic Versioning (https://semver.org/)
-version: 1.2.0
+version: 1.2.1
 
 # This is the version number of the application being deployed. This version number should be
 # incremented each time you make changes to the application. Versions are not expected to

+ 0 - 2
chart/readme.md

@@ -24,9 +24,7 @@ The variables that _must_ be configured are:
 Currently this chart does _not_ support:
 
 - Hidden services
-- Single Sign-On
 - Swift
-- configurations using `WEB_DOMAIN`
 
 # Upgrading
 

+ 224 - 0
chart/templates/configmap-env.yaml

@@ -21,6 +21,9 @@ data:
   ES_PORT: "9200"
   {{- end }}
   LOCAL_DOMAIN: {{ .Values.mastodon.local_domain }}
+  {{- if .Values.mastodon.web_domain }}
+  WEB_DOMAIN: {{ .Values.mastodon.web_domain }}
+  {{- end }}
   # https://devcenter.heroku.com/articles/tuning-glibc-memory-behavior
   MALLOC_ARENA_MAX: "2"
   NODE_ENV: "production"
@@ -36,6 +39,9 @@ data:
   {{- if .Values.mastodon.s3.region }}
   S3_REGION: {{ .Values.mastodon.s3.region }}
   {{- end }}
+  {{- if .Values.mastodon.s3.alias_host }}
+  S3_ALIAS_HOST: {{ .Values.mastodon.s3.alias_host}}
+  {{- end }}
   {{- end }}
   {{- if .Values.mastodon.smtp.auth_method }}
   SMTP_AUTH_METHOD: {{ .Values.mastodon.smtp.auth_method }}
@@ -77,3 +83,221 @@ data:
   SMTP_TLS: {{ .Values.mastodon.smtp.tls | quote }}
   {{- end }}
   STREAMING_CLUSTER_NUM: {{ .Values.mastodon.streaming.workers | quote }}
+  {{- if .Values.externalAuth.oidc.enabled }}
+  OIDC_ENABLED: {{ .Values.externalAuth.oidc.enabled | quote }}
+  OIDC_DISPLAY_NAME: {{ .Values.externalAuth.oidc.display_name }}
+  OIDC_ISSUER: {{ .Values.externalAuth.oidc.issuer }}
+  OIDC_DISCOVERY: {{ .Values.externalAuth.oidc.discovery | quote }}
+  OIDC_SCOPE: {{ .Values.externalAuth.oidc.scope | quote }}
+  OIDC_UID_FIELD: {{ .Values.externalAuth.oidc.uid_field }}
+  OIDC_CLIENT_ID: {{ .Values.externalAuth.oidc.client_id }}
+  OIDC_CLIENT_SECRET: {{ .Values.externalAuth.oidc.client_secret }}
+  OIDC_REDIRECT_URI: {{ .Values.externalAuth.oidc.redirect_uri }}
+  OIDC_SECURITY_ASSUME_EMAIL_IS_VERIFIED: {{ .Values.externalAuth.oidc.assume_email_is_verified | quote }}
+  {{- if .Values.externalAuth.oidc.client_auth_method }}
+  OIDC_CLIENT_AUTH_METHOD: {{ .Values.externalAuth.oidc.client_auth_method }}
+  {{- end }}
+  {{- if .Values.externalAuth.oidc.response_type }}
+  OIDC_RESPONSE_TYPE: {{ .Values.externalAuth.oidc.response_type }}
+  {{- end }}
+  {{- if .Values.externalAuth.oidc.response_mode }}
+  OIDC_RESPONSE_MODE: {{ .Values.externalAuth.oidc.response_mode }}
+  {{- end }}
+  {{- if .Values.externalAuth.oidc.display }}
+  OIDC_DISPLAY: {{ .Values.externalAuth.oidc.display }}
+  {{- end }}
+  {{- if .Values.externalAuth.oidc.prompt }}
+  OIDC_PROMPT: {{ .Values.externalAuth.oidc.prompt }}
+  {{- end }}
+  {{- if .Values.externalAuth.oidc.send_nonce }}
+  OIDC_SEND_NONCE: {{ .Values.externalAuth.oidc.send_nonce }}
+  {{- end }}
+  {{- if .Values.externalAuth.oidc.send_scope_to_token_endpoint }}
+  OIDC_SEND_SCOPE_TO_TOKEN_ENDPOINT: {{ .Values.externalAuth.oidc.send_scope_to_token_endpoint | quote }}
+  {{- end }}
+  {{- if .Values.externalAuth.oidc.idp_logout_redirect_uri }}
+  OIDC_IDP_LOGOUT_REDIRECT_URI: {{ .Values.externalAuth.oidc.idp_logout_redirect_uri }}
+  {{- end }}
+  {{- if .Values.externalAuth.oidc.http_scheme }}
+  OIDC_HTTP_SCHEME: {{ .Values.externalAuth.oidc.http_scheme }}
+  {{- end }}
+  {{- if .Values.externalAuth.oidc.host }}
+  OIDC_HOST: {{ .Values.externalAuth.oidc.host }}
+  {{- end }}
+  {{- if .Values.externalAuth.oidc.port }}
+  OIDC_PORT: {{ .Values.externalAuth.oidc.port }}
+  {{- end }}
+  {{- if .Values.externalAuth.oidc.jwks_uri }}
+  OIDC_JWKS_URI: {{ .Values.externalAuth.oidc.jwks_uri }}
+  {{- end }}
+  {{- if .Values.externalAuth.oidc.auth_endpoint }}
+  OIDC_AUTH_ENDPOINT: {{ .Values.externalAuth.oidc.auth_endpoint }}
+  {{- end }}
+  {{- if .Values.externalAuth.oidc.token_endpoint }}
+  OIDC_TOKEN_ENDPOINT: {{ .Values.externalAuth.oidc.token_endpoint }}
+  {{- end }}
+  {{- if .Values.externalAuth.oidc.user_info_endpoint }}
+  OIDC_USER_INFO_ENDPOINT: {{ .Values.externalAuth.oidc.user_info_endpoint }}
+  {{- end }}
+  {{- if .Values.externalAuth.oidc.end_session_endpoint }}
+  OIDC_END_SESSION_ENDPOINT: {{ .Values.externalAuth.oidc.end_session_endpoint }}
+  {{- end }}
+  {{- end }}
+  {{- if .Values.externalAuth.saml.enabled }}
+  SAML_ENABLED: {{ .Values.externalAuth.saml.enabled | quote }}
+  SAML_ACS_URL: {{ .Values.externalAuth.saml.acs_url }}
+  SAML_ISSUER: {{ .Values.externalAuth.saml.issuer }}
+  SAML_IDP_SSO_TARGET_URL: {{ .Values.externalAuth.saml.idp_sso_target_url }}
+  SAML_IDP_CERT: {{ .Values.externalAuth.saml.idp_cert | quote }}
+  {{- if .Values.externalAuth.saml.idp_cert_fingerprint }}
+  SAML_IDP_CERT_FINGERPRINT: {{ .Values.externalAuth.saml.idp_cert_fingerprint | quote }}
+  {{- end }}
+  {{- if .Values.externalAuth.saml.name_identifier_format }}
+  SAML_NAME_IDENTIFIER_FORMAT: {{ .Values.externalAuth.saml.name_identifier_format }}
+  {{- end }}
+  {{- if .Values.externalAuth.saml.cert }}
+  SAML_CERT: {{ .Values.externalAuth.saml.cert | quote }}
+  {{- end }}
+  {{- if .Values.externalAuth.saml.private_key }}
+  SAML_PRIVATE_KEY: {{ .Values.externalAuth.saml.private_key | quote }}
+  {{- end }}
+  {{- if .Values.externalAuth.saml.want_assertion_signed }}
+  SAML_SECURITY_WANT_ASSERTION_SIGNED: {{ .Values.externalAuth.saml.want_assertion_signed | quote }}
+  {{- end }}
+  {{- if .Values.externalAuth.saml.want_assertion_encrypted }}
+  SAML_SECURITY_WANT_ASSERTION_ENCRYPTED: {{ .Values.externalAuth.saml.want_assertion_encrypted | quote }}
+  {{- end }}
+  {{- if .Values.externalAuth.saml.assume_email_is_verified }}
+  SAML_SECURITY_ASSUME_EMAIL_IS_VERIFIED: {{ .Values.externalAuth.saml.assume_email_is_verified | quote }}
+  {{- end }}
+  {{- if .Values.externalAuth.saml.uid_attribute }}
+  SAML_UID_ATTRIBUTE: {{ .Values.externalAuth.saml.uid_attribute }}
+  {{- end }}
+  {{- if .Values.externalAuth.saml.attributes_statements.uid }}
+  SAML_ATTRIBUTES_STATEMENTS_UID: {{ .Values.externalAuth.saml.attributes_statements.uid | quote }}
+  {{- end }}
+  {{- if .Values.externalAuth.saml.attributes_statements.email }}
+  SAML_ATTRIBUTES_STATEMENTS_EMAIL: {{ .Values.externalAuth.saml.attributes_statements.email | quote }}
+  {{- end }}
+  {{- if .Values.externalAuth.saml.attributes_statements.full_name }}
+  SAML_ATTRIBUTES_STATEMENTS_FULL_NAME: {{ .Values.externalAuth.saml.attributes_statements.full_name | quote }}
+  {{- end }}
+  {{- if .Values.externalAuth.saml.attributes_statements.first_name }}
+  SAML_ATTRIBUTES_STATEMENTS_FIRST_NAME: {{ .Values.externalAuth.saml.attributes_statements.first_name | quote }}
+  {{- end }}
+  {{- if .Values.externalAuth.saml.attributes_statements.last_name }}
+  SAML_ATTRIBUTES_STATEMENTS_LAST_NAME: {{ .Values.externalAuth.saml.attributes_statements.last_name | quote }}
+  {{- end }}
+  {{- if .Values.externalAuth.saml.attributes_statements.verified }}
+  SAML_ATTRIBUTES_STATEMENTS_VERIFIED: {{ .Values.externalAuth.saml.attributes_statements.verified | quote }}
+  {{- end }}
+  {{- if .Values.externalAuth.saml.attributes_statements.verified_email }}
+  SAML_ATTRIBUTES_STATEMENTS_VERIFIED_EMAIL: {{ .Values.externalAuth.saml.attributes_statements.verified_email | quote }}
+  {{- end }}
+  {{- end }}
+  {{- if .Values.externalAuth.oauth_global.oauth_redirect_at_sign_in }}
+  OAUTH_REDIRECT_AT_SIGN_IN: {{ .Values.externalAuth.oauth_global.oauth_redirect_at_sign_in | quote }}
+  {{- end }}
+  {{- if .Values.externalAuth.cas.enabled }}
+  CAS_ENABLED: {{ .Values.externalAuth.cas.enabled | quote }}
+  CAS_URL: {{ .Values.externalAuth.cas.url }}
+  CAS_HOST: {{ .Values.externalAuth.cas.host }}
+  CAS_PORT: {{ .Values.externalAuth.cas.port }}
+  CAS_SSL: {{ .Values.externalAuth.cas.ssl | quote }}
+  {{- if .Values.externalAuth.cas.validate_url }}
+  CAS_VALIDATE_URL: {{ .Values.externalAuth.cas.validate_url }}
+  {{- end }}
+  {{- if .Values.externalAuth.cas.callback_url }}
+  CAS_CALLBACK_URL: {{ .Values.externalAuth.cas.callback_url }}
+  {{- end }}
+  {{- if .Values.externalAuth.cas.logout_url }}
+  CAS_LOGOUT_URL: {{ .Values.externalAuth.cas.logout_url }}
+  {{- end }}
+  {{- if .Values.externalAuth.cas.login_url }}
+  CAS_LOGIN_URL: {{ .Values.externalAuth.cas.login_url }}
+  {{- end }}
+  {{- if .Values.externalAuth.cas.uid_field }}
+  CAS_UID_FIELD: {{ .Values.externalAuth.cas.uid_field | quote }}
+  {{- end }}
+  {{- if .Values.externalAuth.cas.ca_path }}
+  CAS_CA_PATH: {{ .Values.externalAuth.cas.ca_path }}
+  {{- end }}
+  {{- if .Values.externalAuth.cas.disable_ssl_verification }}
+  CAS_DISABLE_SSL_VERIFICATION: {{ .Values.externalAuth.cas.disable_ssl_verification | quote }}
+  {{- end }}
+  {{- if .Values.externalAuth.cas.assume_email_is_verified }}
+  CAS_SECURITY_ASSUME_EMAIL_IS_VERIFIED: {{ .Values.externalAuth.cas.assume_email_is_verified | quote }}
+  {{- end }}
+  {{- if .Values.externalAuth.cas.keys.uid }}
+  CAS_UID_KEY: {{ .Values.externalAuth.cas.keys.uid | quote }}
+  {{- end }}
+  {{- if .Values.externalAuth.cas.keys.name }}
+  CAS_NAME_KEY: {{ .Values.externalAuth.cas.keys.name | quote }}
+  {{- end }}
+  {{- if .Values.externalAuth.cas.keys.email }}
+  CAS_EMAIL_KEY: {{ .Values.externalAuth.cas.keys.email | quote }}
+  {{- end }}
+  {{- if .Values.externalAuth.cas.keys.nickname }}
+  CAS_NICKNAME_KEY: {{ .Values.externalAuth.cas.keys.nickname | quote }}
+  {{- end }}
+  {{- if .Values.externalAuth.cas.keys.first_name }}
+  CAS_FIRST_NAME_KEY: {{ .Values.externalAuth.cas.keys.first_name | quote }}
+  {{- end }}
+  {{- if .Values.externalAuth.cas.keys.last_name }}
+  CAS_LAST_NAME_KEY: {{ .Values.externalAuth.cas.keys.last_name | quote }}
+  {{- end }}
+  {{- if .Values.externalAuth.cas.keys.location }}
+  CAS_LOCATION_KEY: {{ .Values.externalAuth.cas.keys.location | quote }}
+  {{- end }}
+  {{- if .Values.externalAuth.cas.keys.image }}
+  CAS_IMAGE_KEY: {{ .Values.externalAuth.cas.keys.image | quote }}
+  {{- end }}
+  {{- if .Values.externalAuth.cas.keys.phone }}
+  CAS_PHONE_KEY: {{ .Values.externalAuth.cas.keys.phone | quote }}
+  {{- end }}
+  {{- end }}
+  {{- if .Values.externalAuth.pam.enabled }}
+  PAM_ENABLED: {{ .Values.externalAuth.pam.enabled | quote }}
+  {{- if .Values.externalAuth.pam.email_domain }}
+  PAM_EMAIL_DOMAIN: {{ .Values.externalAuth.pam.email_domain }}
+  {{- end }}
+  {{- if .Values.externalAuth.pam.default_service }}
+  PAM_DEFAULT_SERVICE: {{ .Values.externalAuth.pam.default_service }}
+  {{- end }}
+  {{- if .Values.externalAuth.pam.controlled_service }}
+  PAM_CONTROLLED_SERVICE: {{ .Values.externalAuth.pam.controlled_service }}
+  {{- end }}
+  {{- end }}
+  {{- if .Values.externalAuth.ldap.enabled }}
+  LDAP_ENABLED: {{ .Values.externalAuth.ldap.enabled | quote }}
+  LDAP_HOST: {{ .Values.externalAuth.ldap.host }}
+  LDAP_PORT: {{ .Values.externalAuth.ldap.port }}
+  LDAP_METHOD: {{ .Values.externalAuth.ldap.method }}
+  {{- if .Values.externalAuth.ldap.base }}
+  LDAP_BASE: {{ .Values.externalAuth.ldap.base }}
+  {{- end }}
+  {{- if .Values.externalAuth.ldap.bind_on }}
+  LDAP_BIND_ON: {{ .Values.externalAuth.ldap.bind_on }}
+  {{- end }}
+  {{- if .Values.externalAuth.ldap.password }}
+  LDAP_PASSWORD: {{ .Values.externalAuth.ldap.password }}
+  {{- end }}
+  {{- if .Values.externalAuth.ldap.uid }}
+  LDAP_UID: {{ .Values.externalAuth.ldap.uid }}
+  {{- end }}
+  {{- if .Values.externalAuth.ldap.mail }}
+  LDAP_MAIL: {{ .Values.externalAuth.ldap.mail }}
+  {{- end }}
+  {{- if .Values.externalAuth.ldap.search_filter }}
+  LDAP_SEARCH_FILTER: {{ .Values.externalAuth.ldap.search_filter }}
+  {{- end }}
+  {{- if .Values.externalAuth.ldap.uid_conversion.enabled }}
+  LDAP_UID_CONVERSION_ENABLED: {{ .Values.externalAuth.ldap.uid_conversion.enabled | quote }}
+  {{- end }}
+  {{- if .Values.externalAuth.ldap.uid_conversion.search }}
+  LDAP_UID_CONVERSION_SEARCH: {{ .Values.externalAuth.ldap.uid_conversion.search }}
+  {{- end }}
+  {{- if .Values.externalAuth.ldap.uid_conversion.replace }}
+  LDAP_UID_CONVERSION_REPLACE: {{ .Values.externalAuth.ldap.uid_conversion.replace }}
+  {{- end }}
+  {{- end }}

+ 104 - 0
chart/values.yaml

@@ -27,6 +27,9 @@ mastodon:
   # available locales: https://github.com/tootsuite/mastodon/blob/master/config/application.rb#L43
   locale: en
   local_domain: mastodon.local
+  # Use of WEB_DOMAIN requires careful consideration: https://docs.joinmastodon.org/admin/config/#federation
+  # You must redirect the path LOCAL_DOMAIN/.well-known/ to WEB_DOMAIN/.well-known/ as described
+  # web_domain: mastodon.example.com
   persistence:
     assets:
       # ReadWriteOnce is more widely supported than ReadWriteMany, but limits
@@ -49,6 +52,8 @@ mastodon:
     endpoint: https://us-east-1.linodeobjects.com
     hostname: us-east-1.linodeobjects.com
     region: ""
+    # If you have a caching proxy, enter its base URL here.
+    alias_host: ""
   # these must be set manually; autogenerated keys are rotated on each upgrade
   secrets:
     secret_key_base: ""
@@ -136,6 +141,105 @@ service:
   type: ClusterIP
   port: 80
 
+externalAuth:
+  oidc:
+    # OpenID Connect support is proposed in PR #16221 and awaiting merge.
+    enabled: false
+    # display_name: "example-label"
+    # issuer: https://login.example.space/auth/realms/example-space
+    # discovery: true
+    # scope: "openid,profile"
+    # uid_field: uid
+    # client_id: mastodon
+    # client_secret: SECRETKEY
+    # redirect_uri: https://example.com/auth/auth/openid_connect/callback
+    # assume_email_is_verified: true
+    # client_auth_method: 
+    # response_type: 
+    # response_mode: 
+    # display: 
+    # prompt: 
+    # send_nonce: 
+    # send_scope_to_token_endpoint: 
+    # idp_logout_redirect_uri: 
+    # http_scheme: 
+    # host: 
+    # port: 
+    # jwks_uri: 
+    # auth_endpoint: 
+    # token_endpoint: 
+    # user_info_endpoint: 
+    # end_session_endpoint: 
+  saml:
+    enabled: false
+    # acs_url: http://mastodon.example.com/auth/auth/saml/callback
+    # issuer: mastodon
+    # idp_sso_target_url: https://login.example.com/auth/realms/example/protocol/saml
+    # idp_cert: '-----BEGIN CERTIFICATE-----[your_cert_content]-----END CERTIFICATE-----'
+    # idp_cert_fingerprint: 
+    # name_identifier_format: urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified
+    # cert: 
+    # private_key: 
+    # want_assertion_signed: true
+    # want_assertion_encrypted: true
+    # assume_email_is_verified: true
+    # uid_attribute: "urn:oid:0.9.2342.19200300.100.1.1"
+    # attributes_statements: 
+    #   uid: "urn:oid:0.9.2342.19200300.100.1.1"
+    #   email: "urn:oid:1.3.6.1.4.1.5923.1.1.1.6"
+    #   full_name: "urn:oid:2.16.840.1.113730.3.1.241"
+    #   first_name: "urn:oid:2.5.4.42"
+    #   last_name: "urn:oid:2.5.4.4"
+    #   verified: 
+    #   verified_email: 
+  oauth_global: 
+    # Force redirect local login to CAS. Does not function with SAML or LDAP.
+    oauth_redirect_at_sign_in: false
+  cas:
+    enabled: false
+    # url: https://sso.myserver.com
+    # host: sso.myserver.com
+    # port: 443
+    # ssl: true
+    # validate_url: 
+    # callback_url: 
+    # logout_url: 
+    # login_url: 
+    # uid_field: 'user'
+    # ca_path: 
+    # disable_ssl_verification: false
+    # assume_email_is_verified: true
+    # keys: 
+    #   uid: 'user'
+    #   name: 'name'
+    #   email: 'email'
+    #   nickname: 'nickname'
+    #   first_name: 'firstname'
+    #   last_name: 'lastname'
+    #   location: 'location'
+    #   image: 'image'
+    #   phone: 'phone'
+  pam: 
+    enabled: false
+    # email_domain: example.com
+    # default_service: rpam
+    # controlled_service: rpam
+  ldap:
+    enabled: false
+    # host: myservice.namespace.svc
+    # port: 389
+    # method: simple_tls
+    # base: 
+    # bind_on: 
+    # password: 
+    # uid: cn
+    # mail: mail
+    # search_filter: "(|(%{uid}=%{email})(%{mail}=%{email}))"
+    # uid_conversion:
+    #   enabled: true
+    #   search: "., -"
+    #   replace: _
+
 # https://github.com/tootsuite/mastodon/blob/master/Dockerfile#L88
 #
 # if you manually change the UID/GID environment variables, ensure these values