File size: 1,997 Bytes
91994bf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import os
from typing import List, Sequence

# Blocked keys that should never be used in production
DEFAULT_BLOCKLIST = {
    "demo_key_12345",
    "pro_key_67890",
    "enterprise_key_abcde",
    "qulab_master_key_2025",
    "qulab_demo_key",
}

# Words that typically indicate a placeholder or sample secret
PLACEHOLDER_KEYWORDS = ("changeme", "example", "sample", "demo", "test", "placeholder")


def _contains_placeholder(key: str, placeholder_keywords: Sequence[str]) -> bool:
    """Check if a key contains placeholder keywords."""
    lower_key = key.lower()
    return any(word in lower_key for word in placeholder_keywords)


def load_api_keys_from_env(
    env_var: str = "QU_LAB_MASTER_KEYS",
    *,
    blocklist: Sequence[str] = DEFAULT_BLOCKLIST,
    placeholder_keywords: Sequence[str] = PLACEHOLDER_KEYWORDS,
) -> List[str]:
    """
    Load API keys from an environment variable and validate them.

    The environment variable should contain a comma-separated list of API keys.
    Raises a RuntimeError if the variable is unset, empty, or includes default/placeholder keys.
    """
    raw_keys = os.getenv(env_var, "")
    if not raw_keys:
        raise RuntimeError(
            f"{env_var} must be set to a comma-separated list of secure API keys; "
            "startup aborted because no keys were provided."
        )

    keys = [key.strip() for key in raw_keys.split(",") if key.strip()]
    if not keys:
        raise RuntimeError(
            f"{env_var} was provided but did not contain any usable keys; "
            "please supply at least one non-empty key."
        )

    invalid_keys = [
        key
        for key in keys
        if key in blocklist or _contains_placeholder(key, placeholder_keywords)
    ]
    if invalid_keys:
        raise RuntimeError(
            f"{env_var} includes default or placeholder keys ({', '.join(invalid_keys)}); "
            "replace them with unique, secret values before starting the service."
        )

    return keys