Skip to content

Commit

Permalink
fix: improve .env.example for devs, better default secrets
Browse files Browse the repository at this point in the history
  • Loading branch information
danielgrittner committed Aug 21, 2024
1 parent d90d64d commit 997a675
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 33 deletions.
3 changes: 2 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
ADMYRAL_DISABLE_NSJAIL=true # outside of docker, we don't use nsjail
# outside of docker, we don't use nsjail
ADMYRAL_DISABLE_NSJAIL=true

# used for generating migrations
MIGRATION_DATABASE_URL=sqlite+aiosqlite:///.admyral/migration.db
12 changes: 8 additions & 4 deletions admyral/config/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,13 +163,17 @@ def get_temporal_daemon_log_file() -> str:


ENV_ADMYRAL_WEBHOOK_SIGNING_SECRET = "ADMYRAL_WEBHOOK_SIGNING_SECRET"
WEBHOOK_SIGNING_SECRET = os.getenv(
ENV_ADMYRAL_WEBHOOK_SIGNING_SECRET, "e179017a-62b0-4996-8a38-e91aa9f1"
WEBHOOK_SIGNING_SECRET = bytes.fromhex(
os.getenv(
ENV_ADMYRAL_WEBHOOK_SIGNING_SECRET, "ebedd9f0c10b01acb9fd097cdf34a2b38bb554f2c7f68f0d9f534eff5c6ef5d9"
)
)

ENV_ADMYRAL_SECRETS_ENCRYPTION_KEY = "ADMYRAL_SECRETS_ENCRYPTION_KEY"
SECRETS_ENCRYPTION_KEY = os.getenv(
ENV_ADMYRAL_SECRETS_ENCRYPTION_KEY, "0123456789abcdef0123456789abcdef"
SECRETS_ENCRYPTION_KEY = bytes.fromhex(
os.getenv(
ENV_ADMYRAL_SECRETS_ENCRYPTION_KEY, "834f01cf391c972f1e6def3d7f315f8194bb10048e5cf282aa4cba63b239d8fb"
)
)


Expand Down
16 changes: 9 additions & 7 deletions admyral/utils/crypto.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,20 @@
from admyral.config.config import WEBHOOK_SIGNING_SECRET, SECRETS_ENCRYPTION_KEY


def _generate_hs256(secret: bytes, data: str) -> str:
return hmac.new(secret, data.encode(), hashlib.sha256).hexdigest()


def generate_hs256(data: str) -> str:
return hmac.new(
WEBHOOK_SIGNING_SECRET.encode(), data.encode(), hashlib.sha256
).hexdigest()
return _generate_hs256(WEBHOOK_SIGNING_SECRET, data)


def encrypt_aes256_gcm(secret_key: str, plaintext: str) -> str:
def encrypt_aes256_gcm(secret_key: bytes, plaintext: str) -> str:
# Generate a random 96-bit IV (Initialization Vector)
iv = os.urandom(12)

# Create AES-GCM cipher object
aes_gcm = AESGCM(secret_key.encode())
aes_gcm = AESGCM(secret_key)

# Encrypt the plaintext and get the associated ciphertext
ciphertext = aes_gcm.encrypt(iv, plaintext.encode(), None)
Expand All @@ -34,7 +36,7 @@ def encrypt_secret(plaintext: str) -> str:
return encrypt_aes256_gcm(SECRETS_ENCRYPTION_KEY, plaintext)


def decrypt_aes256_gcm(secret_key: str, iv_ciphertext_b64: str) -> str:
def decrypt_aes256_gcm(secret_key: bytes, iv_ciphertext_b64: str) -> str:
# Decode the base64 encoded IV and ciphertext
iv_ciphertext = urlsafe_b64decode(iv_ciphertext_b64)

Expand All @@ -43,7 +45,7 @@ def decrypt_aes256_gcm(secret_key: str, iv_ciphertext_b64: str) -> str:
ciphertext = iv_ciphertext[12:]

# Create AES-GCM cipher object
aes_gcm = AESGCM(secret_key.encode())
aes_gcm = AESGCM(secret_key)

# Decrypt the ciphertext
plaintext = aes_gcm.decrypt(iv, ciphertext, None)
Expand Down
4 changes: 2 additions & 2 deletions deploy/docker-compose/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ RESEND_EMAIL=""
ADMYRAL_WORKER_REPLICAS=1

# HS256 Key
ADMYRAL_WEBHOOK_SIGNING_SECRET=e179017a-62b0-4996-8a38-e91aa9f1
ADMYRAL_WEBHOOK_SIGNING_SECRET=ebedd9f0c10b01acb9fd097cdf34a2b38bb554f2c7f68f0d9f534eff5c6ef5d9
# AES-256 GCM Key
ADMYRAL_SECRETS_ENCRYPTION_KEY=0123456789abcdef0123456789abcdef
ADMYRAL_SECRETS_ENCRYPTION_KEY=834f01cf391c972f1e6def3d7f315f8194bb10048e5cf282aa4cba63b239d8fb


POSTGRES_PASSWORD=your-super-secret-and-long-postgres-password
Expand Down
6 changes: 3 additions & 3 deletions deploy/docker-compose/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ services:
- ADMYRAL_DATABASE_URL=postgresql+asyncpg://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-your-super-secret-and-long-postgres-password}@postgresql:5432/admyral
- ADMYRAL_SECRETS_MANAGER_TYPE=sql
# App Secrets
- ADMYRAL_WEBHOOK_SIGNING_SECRET=${ADMYRAL_WEBHOOK_SIGNING_SECRET:-e179017a-62b0-4996-8a38-e91aa9f1}
- ADMYRAL_SECRETS_ENCRYPTION_KEY=${ADMYRAL_SECRETS_ENCRYPTION_KEY:-0123456789abcdef0123456789abcdef}
- ADMYRAL_WEBHOOK_SIGNING_SECRET=${ADMYRAL_WEBHOOK_SIGNING_SECRET:-ebedd9f0c10b01acb9fd097cdf34a2b38bb554f2c7f68f0d9f534eff5c6ef5d9}
- ADMYRAL_SECRETS_ENCRYPTION_KEY=${ADMYRAL_SECRETS_ENCRYPTION_KEY:-834f01cf391c972f1e6def3d7f315f8194bb10048e5cf282aa4cba63b239d8fb}
# Temporal
- ADMYRAL_TEMPORAL_HOST=temporal:7233

Expand Down Expand Up @@ -98,7 +98,7 @@ services:
- ADMYRAL_DATABASE_URL=postgresql+asyncpg://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-your-super-secret-and-long-postgres-password}@postgresql:5432/admyral
- ADMYRAL_SECRETS_MANAGER_TYPE=sql
# App Secrets
- ADMYRAL_SECRETS_ENCRYPTION_KEY=${ADMYRAL_SECRETS_ENCRYPTION_KEY:-0123456789abcdef0123456789abcdef}
- ADMYRAL_SECRETS_ENCRYPTION_KEY=${ADMYRAL_SECRETS_ENCRYPTION_KEY:-834f01cf391c972f1e6def3d7f315f8194bb10048e5cf282aa4cba63b239d8fb}
# Temporal
- ADMYRAL_TEMPORAL_HOST=temporal:7233

Expand Down
32 changes: 16 additions & 16 deletions scripts/generate_secrets.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,24 @@ generate_jwt () {
echo "${jwt_header}.${jwt_payload}.${hmac_signature}"
}

secret=$(openssl rand -hex 32)
secret_base64=$(echo "$secret" | tr -d '\n' | base64)
# secret=$(openssl rand -hex 32)
# secret_base64=$(echo "$secret" | tr -d '\n' | base64)

iat=$(date +%s)
exp=$((iat + 60 * 60 * 24 * 365 * 5))
# iat=$(date +%s)
# exp=$((iat + 60 * 60 * 24 * 365 * 5))

orig_anon_key_payload='{"role":"anon","iss":"supabase","iat":0,"exp":0}'
anon_key_payload=$(echo "$orig_anon_key_payload" | jq --arg iat "$iat" --arg exp "$exp" '.iat = ($iat | tonumber) | .exp = ($exp | tonumber)')
jwt_anon_key=$(generate_jwt "$anon_key_payload" "$secret")
# orig_anon_key_payload='{"role":"anon","iss":"supabase","iat":0,"exp":0}'
# anon_key_payload=$(echo "$orig_anon_key_payload" | jq --arg iat "$iat" --arg exp "$exp" '.iat = ($iat | tonumber) | .exp = ($exp | tonumber)')
# jwt_anon_key=$(generate_jwt "$anon_key_payload" "$secret")

orig_service_key_payload='{"role":"service_role","iss":"supabase","iat":0,"exp":0}'
service_key_payload=$(echo "$orig_service_key_payload" | jq --arg iat "$iat" --arg exp "$exp" '.iat = ($iat | tonumber) | .exp = ($exp | tonumber)')
service_role_key=$(generate_jwt "$service_key_payload" "$secret")
# orig_service_key_payload='{"role":"service_role","iss":"supabase","iat":0,"exp":0}'
# service_key_payload=$(echo "$orig_service_key_payload" | jq --arg iat "$iat" --arg exp "$exp" '.iat = ($iat | tonumber) | .exp = ($exp | tonumber)')
# service_role_key=$(generate_jwt "$service_key_payload" "$secret")

echo "POSTGRES_PASSWORD=$(openssl rand -hex 32)"
echo "JWT_SECRET=$secret_base64"
echo "ANON_KEY=$jwt_anon_key"
echo "SERVICE_ROLE_KEY=$service_role_key"
echo "CREDENTIALS_SECRET=$(openssl rand -hex 32)"
echo "WEBHOOK_SIGNING_SECRET=$(openssl rand -hex 32)"
echo "DASHBOARD_PASSWORD=$(openssl rand -hex 32)"
echo "ADMYRAL_SECRETS_ENCRYPTION_KEY=$(openssl rand -hex 32)"
echo "ADMYRAL_WEBHOOK_SIGNING_SECRET=$(openssl rand -hex 32)"
# echo "JWT_SECRET=$secret_base64"
# echo "ANON_KEY=$jwt_anon_key"
# echo "SERVICE_ROLE_KEY=$service_role_key"
# echo "DASHBOARD_PASSWORD=$(openssl rand -hex 32)"
Empty file added tests/utils/__init__.py
Empty file.
16 changes: 16 additions & 0 deletions tests/utils/test_crypto.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from admyral.utils.crypto import encrypt_aes256_gcm, decrypt_aes256_gcm, _generate_hs256


TEST_SECRET = bytes.fromhex("834f01cf391c972f1e6def3d7f315f8194bb10048e5cf282aa4cba63b239d8fb")


def test_encrypt_decrypt():
msg = "this is my encrypted message - hello world!"
ciphertext = encrypt_aes256_gcm(TEST_SECRET, "this is my encrypted message - hello world!")
deciphered = decrypt_aes256_gcm(TEST_SECRET, ciphertext)
assert deciphered == msg


def test_hs256():
h = _generate_hs256(TEST_SECRET, "this is my securely hashed message - hello world!")
assert h is not None

0 comments on commit 997a675

Please sign in to comment.