This commit is contained in:
2026-10-26 20:33:41 -04:00
parent e048f579a2
commit 827ec93663
6 changed files with 31 additions and 2 deletions
+8
View File
@@ -79,6 +79,14 @@ Stripe needs `STRIPE_PORTAL_CONFIGURATION`. SMTP STARTTLS, production PostgreSQL
and HTTPS are required; production SQLite is rejected. A complete override of
`www_membership_environment` is possible but must preserve mandatory defaults.
LDAP uses verified LDAPS/StartTLS by default. For deliberate plaintext LDAP
inside a trusted cluster, set `LDAP_URL: ldap://openldap.openldap.svc.cluster.local:389`
and `LDAP_ALLOW_INSECURE: "1"` in `www_membership_environment_overrides`, then
redeploy with a membership image containing this option. This applies to both web
and worker and sends bind/registration passwords and directory data unencrypted.
The default is `"0"`; `ldaps://` remains certificate-verified regardless of this
option. There is no automatic downgrade after a TLS failure.
Payment flags validate operator intent; **actual application availability is
controlled by its environment, secrets and tiers**. Disabling Stripe validation
alone does not remove its button. Set an empty tier mapping to disable all paid
+1
View File
@@ -70,6 +70,7 @@ www_membership_environment:
DEX_CLIENT_ID: www-membership
DEX_CONNECTOR_ID: www-ldap
LDAP_URL: ldaps://ldap.example.com
LDAP_ALLOW_INSECURE: "0"
LDAP_BIND_DN: ""
LDAP_ACCOUNT_BASE_DN: ou=www,ou=people,dc=example,dc=com
LDAP_SEARCH_BASE_DN: ou=people,dc=example,dc=com
+1
View File
@@ -27,6 +27,7 @@
- www_membership_environment.EMAIL_USE_TLS | string == '1'
- www_membership_environment.DEX_ISSUER is match('^https://[^/@]+')
- www_membership_environment.LDAP_URL is match('^ldaps?://[^/@]+')
- (www_membership_environment.LDAP_ALLOW_INSECURE | default('0') | string) in ['0', '1']
- not www_membership_shkeeper_enabled or (www_membership_environment.SHKEEPER_URL is match('^https://[^/@]+') and www_membership_environment.SHKEEPER_CURRENCIES | length > 0)
- www_membership_shkeeper_enabled or (www_membership_environment.SHKEEPER_URL | length == 0 and www_membership_environment.SHKEEPER_CURRENCIES | length == 0)
- not www_membership_stripe_enabled or www_membership_environment.STRIPE_PORTAL_CONFIGURATION | length > 0
+4
View File
@@ -6,6 +6,10 @@ www_repo_version: refs/heads/main
www_membership_secret_name: www-membership-credentials
www_membership_shkeeper_enabled: true
www_membership_environment_overrides:
# Optional plaintext LDAP for a trusted cluster only; sends passwords unencrypted.
# Enable BOTH lines together. Omit them to retain the role's verified TLS default.
# LDAP_URL: ldap://openldap.openldap.svc.cluster.local:389
# LDAP_ALLOW_INSECURE: "1"
LDAP_BIND_DN: cn=www-membership,ou=system,dc=eom,dc=dev
LDAP_PASSWORD_SCHEME: "{ARGON2}"
EMAIL_HOST: smtp.eom.dev
+9 -1
View File
@@ -27,12 +27,20 @@
dest: "/tmp/www-test-{{ item }}.yml"
mode: "0600"
loop: [website, membership-config, membership-postgres, membership-migrate, membership-workloads]
- name: Enable explicit plaintext LDAP fixture
ansible.builtin.set_fact:
www_membership_environment: "{{ www_membership_environment | combine({'LDAP_URL': 'ldap://openldap.openldap.svc.cluster.local:389', 'LDAP_ALLOW_INSECURE': '1'}) }}"
- name: Render plaintext LDAP configuration
ansible.builtin.template:
src: ../templates/membership-config.yml.j2
dest: /tmp/www-test-plaintext-membership-config.yml
mode: "0600"
- name: Enable optional external database and private CA fixture
ansible.builtin.set_fact:
www_membership_postgres_managed: false
www_membership_ca_secret_name: private-ca
www_image_pull_secrets: [{name: registry-pull}]
www_membership_environment: "{{ www_membership_environment | combine({'POSTGRES_HOST': 'postgres.example.org', 'POSTGRES_SSLMODE': 'verify-full', 'PGSSLROOTCERT': '/etc/membership/ca/db.pem', 'LDAP_CA_CERT_FILE': '/etc/membership/ca/ldap.pem', 'SHKEEPER_URL': 'https://crypto.example.org', 'SHKEEPER_CURRENCIES': 'BTC,XMR', 'SHKEEPER_CA_CERT_FILE': '/etc/membership/ca/shkeeper.pem'}) }}"
www_membership_environment: "{{ www_membership_environment | combine({'LDAP_URL': 'ldaps://ldap.example.com', 'LDAP_ALLOW_INSECURE': '0', 'POSTGRES_HOST': 'postgres.example.org', 'POSTGRES_SSLMODE': 'verify-full', 'PGSSLROOTCERT': '/etc/membership/ca/db.pem', 'LDAP_CA_CERT_FILE': '/etc/membership/ca/ldap.pem', 'SHKEEPER_URL': 'https://crypto.example.org', 'SHKEEPER_CURRENCIES': 'BTC,XMR', 'SHKEEPER_CA_CERT_FILE': '/etc/membership/ca/shkeeper.pem'}) }}"
- name: Render external provider variants
ansible.builtin.template:
src: "../templates/{{ item }}.yml.j2"
+8 -1
View File
@@ -43,6 +43,12 @@ assert len({(obj["kind"], obj["metadata"]["name"]) for obj in all_objects}) == l
config = find(all_objects, "ConfigMap", "membership-config")["data"]
assert all(isinstance(value, str) for value in config.values())
assert config["MEMBERSHIP_PUBLIC_URL"] == "https://www.eom.dev"
assert config["LDAP_ALLOW_INSECURE"] == "0"
assert config["LDAP_URL"].startswith("ldaps://")
plaintext_config = find(docs("plaintext-membership-config"), "ConfigMap", "membership-config")["data"]
assert plaintext_config["LDAP_ALLOW_INSECURE"] == "1"
assert plaintext_config["LDAP_URL"] == "ldap://openldap.openldap.svc.cluster.local:389"
assert all(isinstance(value, str) for value in plaintext_config.values())
assert "MEMBERSHIP_SECRET_KEY" not in config and "SHKEEPER_API_KEY" not in config
tiers = json.loads(find(all_objects, "ConfigMap", "membership-tiers")["data"]["tiers.json"])
assert len(tiers) == 5 and tiers["level-4"]["usd_amount"] == "64.00"
@@ -83,7 +89,8 @@ for obj in docs("external-membership-workloads"):
external_config = docs("external-membership-config")
assert not any(obj["kind"] == "NetworkPolicy" and obj["metadata"]["name"] == "membership-db" for obj in external_config)
assert find(external_config, "ConfigMap", "membership-config")["data"]["POSTGRES_SSLMODE"] == "verify-full"
assert find(external_config, "ConfigMap", "membership-config")["data"]["LDAP_ALLOW_INSECURE"] == "0"
disabled = docs("disabled-website")
assert not any(obj["kind"] == "OnionService" for obj in disabled)
assert "ProxyPass" not in find(disabled, "ConfigMap", "httpd")["data"]["membership.conf"]
print(f"PASS: {len(all_objects)} Kubernetes objects; default, external/CA/SHKeeper and disabled variants")
print(f"PASS: {len(all_objects)} Kubernetes objects; default, plaintext LDAP, external/CA/SHKeeper and disabled variants")