Skip to content

Commit e396bc5

Browse files
aapelivclaude
andcommitted
Backend: migrate ENABLE_STRONG_VERIFICATION to strong_verification_enabled flag
Replace the static ENABLE_STRONG_VERIFICATION env config with a per-request `strong_verification_enabled` feature flag so strong verification can be toggled remotely without a deploy. The Iris ID credentials stay in env and are now required in production unconditionally (since the flag can be flipped on at any time), failing loudly at boot if missing. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 5ead923 commit e396bc5

5 files changed

Lines changed: 8 additions & 11 deletions

File tree

app/backend.dev.env

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ STRIPE_API_KEY=sk_test_...
1818
STRIPE_WEBHOOK_SECRET=whsec_...
1919
STRIPE_RECURRING_PRODUCT_ID=price_...
2020

21-
ENABLE_STRONG_VERIFICATION=0
2221
IRIS_ID_PUBKEY=public-key-...
2322
IRIS_ID_SECRET=secret-...
2423
# corresponds to private key e6c2fbf3756b387bc09a458a7b85935718ef3eb1c2777ef41d335c9f6c0ab272

app/backend/src/couchers/config.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@
4545
("STRIPE_API_KEY", str),
4646
("STRIPE_WEBHOOK_SECRET", str),
4747
("STRIPE_RECURRING_PRODUCT_ID", str),
48-
# Strong verification through Iris ID
49-
("ENABLE_STRONG_VERIFICATION", bool),
48+
# Strong verification through Iris ID (gated at runtime by the `strong_verification_enabled` feature flag)
5049
("IRIS_ID_PUBKEY", str),
5150
("IRIS_ID_SECRET", str),
5251
("VERIFICATION_DATA_PUBLIC_KEY", bytes),
@@ -151,15 +150,15 @@ def check_config(cfg: dict[str, Any]) -> None:
151150
raise Exception("Production site must have SMS enabled")
152151
if cfg["IN_TEST"]:
153152
raise Exception("IN_TEST while not DEV")
153+
# Strong verification is gated at runtime by the `strong_verification_enabled` feature flag, which
154+
# can be flipped on remotely at any time, so prod must always have the Iris ID credentials present.
155+
if not cfg["IRIS_ID_PUBKEY"] or not cfg["IRIS_ID_SECRET"] or not cfg["VERIFICATION_DATA_PUBLIC_KEY"]:
156+
raise Exception("Iris ID credentials must be configured in production")
154157

155158
if cfg["ENABLE_DONATIONS"]:
156159
if not cfg["STRIPE_API_KEY"] or not cfg["STRIPE_WEBHOOK_SECRET"] or not cfg["STRIPE_RECURRING_PRODUCT_ID"]:
157160
raise Exception("No Stripe API key/recurring donation ID but donations enabled")
158161

159-
if cfg["ENABLE_STRONG_VERIFICATION"]:
160-
if not cfg["IRIS_ID_PUBKEY"] or not cfg["IRIS_ID_SECRET"] or not cfg["VERIFICATION_DATA_PUBLIC_KEY"]:
161-
raise Exception("No Iris ID pubkey/secret or verification data pubkey but strong verification enabled")
162-
163162
if cfg["ENABLE_POSTAL_VERIFICATION"]:
164163
if (
165164
not cfg["MYPOSTCARD_API_KEY"]

app/backend/src/couchers/servicers/account.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,7 @@ def VerifyPhone(
428428
def InitiateStrongVerification(
429429
self, request: empty_pb2.Empty, context: CouchersContext, session: Session
430430
) -> account_pb2.InitiateStrongVerificationRes:
431-
if not config["ENABLE_STRONG_VERIFICATION"]:
431+
if not context.get_boolean_value("strong_verification_enabled", default=False):
432432
context.abort_with_error_code(grpc.StatusCode.UNAVAILABLE, "strong_verification_disabled")
433433

434434
user = session.execute(select(User).where(User.id == context.user_id)).scalar_one()

app/backend/src/tests/conftest.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,6 @@ def testconfig():
181181
config["STRIPE_WEBHOOK_SECRET"] = ""
182182
config["STRIPE_RECURRING_PRODUCT_ID"] = ""
183183

184-
config["ENABLE_STRONG_VERIFICATION"] = False
185184
config["IRIS_ID_PUBKEY"] = ""
186185
config["IRIS_ID_SECRET"] = ""
187186
# corresponds to private key e6c2fbf3756b387bc09a458a7b85935718ef3eb1c2777ef41d335c9f6c0ab272

app/backend/src/tests/test_strong_verification.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,6 @@ def do_and_check_sv(
238238

239239
def monkeypatch_sv_config(monkeypatch):
240240
new_config = config.copy()
241-
new_config["ENABLE_STRONG_VERIFICATION"] = True
242241
new_config["IRIS_ID_PUBKEY"] = "dummy_pubkey"
243242
new_config["IRIS_ID_SECRET"] = "dummy_secret"
244243
new_config["VERIFICATION_DATA_PUBLIC_KEY"] = bytes.fromhex(
@@ -637,7 +636,8 @@ def test_strong_verification_regression2(db, monkeypatch):
637636
)
638637

639638

640-
def test_strong_verification_disabled(db):
639+
def test_strong_verification_disabled(db, feature_flags):
640+
feature_flags.set("strong_verification_enabled", False)
641641
user, token = generate_user()
642642

643643
with account_session(token) as account:

0 commit comments

Comments
 (0)