Skip to content

Commit

Permalink
Merge pull request #165 from oslokommune/runtime-secrets
Browse files Browse the repository at this point in the history
Read secrets at runtime
  • Loading branch information
simenheg committed Feb 19, 2024
2 parents 3b74e26 + ee1a09e commit 06a5f9c
Show file tree
Hide file tree
Showing 12 changed files with 29 additions and 26 deletions.
3 changes: 2 additions & 1 deletion jobs/client_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import requests
from aws_xray_sdk.core import patch_all, xray_recorder
from okdata.aws.logging import logging_wrapper
from okdata.aws.ssm import get_secret
from requests.exceptions import HTTPError

from maskinporten_api.auto_rotate import has_auto_rotate_enabled
Expand Down Expand Up @@ -151,7 +152,7 @@ def _send_email(to_emails, body):
"emne": "Maskinporten klientrapport",
"meldingskropp": body.replace("\n", "<br />"),
},
headers={"apikey": os.environ["EMAIL_API_KEY"]},
headers={"apikey": get_secret("/dataplatform/shared/email-api-key")},
)
res.raise_for_status()
return res
Expand Down
16 changes: 10 additions & 6 deletions maskinporten_api/audit.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import logging
import os
import time
from datetime import datetime, timezone

import boto3
import requests
from boto3.dynamodb.conditions import Key
from botocore.exceptions import ClientError
from okdata.aws.ssm import get_secret

from maskinporten_api.permissions import client_resource_name

Expand Down Expand Up @@ -61,11 +61,15 @@ def audit_log(item_id, action, user, scopes=None, key_id=None):


def audit_notify(header, client_name, env, scopes):
notify_endpoint = os.getenv("SLACK_MASKINPORTEN_API_ALERTS_WEBHOOK_URL")

if not notify_endpoint:
log.warning("No notify endpoint configured")
return
try:
notify_endpoint = get_secret(
"/dataplatform/slack/maskinporten-api-slack-webhook"
)
except ClientError as e:
if e.response["Error"]["Code"] == "AccessDeniedException":
log.warning("No notify endpoint configured")
return
raise

try:
response = requests.post(
Expand Down
2 changes: 1 addition & 1 deletion maskinporten_api/maskinporten_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
import requests
from OpenSSL import crypto
from botocore.exceptions import ClientError
from okdata.aws.ssm import get_secret

from maskinporten_api.jwt_client import JWTAuthClient, JWTConfig
from maskinporten_api.ssm import get_secret
from maskinporten_api.util import getenv
from models import MaskinportenEnvironment

Expand Down
8 changes: 0 additions & 8 deletions maskinporten_api/ssm.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import json
import os
from datetime import datetime, timezone

import boto3
Expand All @@ -8,13 +7,6 @@
from maskinporten_api.keys import Key


def get_secret(key):
"""Return a secret (SecureString) from SSM stored under `key`."""
client = boto3.client("ssm", region_name=os.environ["AWS_REGION"])
response = client.get_parameter(Name=key, WithDecryption=True)
return response["Parameter"]["Value"]


class AssumeRoleAccessDeniedError(Exception):
"""Raised when access is denied when assuming an AWS role."""

Expand Down
10 changes: 7 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ authlib==0.15.4
aws-xray-sdk==2.12.0
# via okdata-maskinporten-api (setup.py)
boto3==1.28.61
# via okdata-maskinporten-api (setup.py)
# via
# okdata-aws
# okdata-maskinporten-api (setup.py)
botocore==1.31.61
# via
# aws-xray-sdk
Expand Down Expand Up @@ -48,11 +50,11 @@ jsonschema==3.2.0
# via okdata-sdk
mangum==0.17.0
# via okdata-maskinporten-api (setup.py)
okdata-aws==1.0.1
okdata-aws==2.1.0
# via okdata-maskinporten-api (setup.py)
okdata-resource-auth==0.1.4
# via okdata-maskinporten-api (setup.py)
okdata-sdk==0.9.2
okdata-sdk==3.1.0
# via okdata-aws
pyasn1==0.4.8
# via
Expand All @@ -78,6 +80,7 @@ python-dateutil==2.8.1
python-jose==3.3.0
# via
# okdata-maskinporten-api (setup.py)
# okdata-sdk
# python-keycloak
python-keycloak==1.8.0
# via
Expand Down Expand Up @@ -117,6 +120,7 @@ typing-extensions==4.8.0
urllib3==1.26.18
# via
# botocore
# okdata-sdk
# python-keycloak
# requests
wrapt==1.15.0
Expand Down
2 changes: 1 addition & 1 deletion resources/authorizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
from fastapi import Depends
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from keycloak import KeycloakOpenID
from okdata.aws.ssm import get_secret
from okdata.resource_auth import ResourceAuthorizer

from maskinporten_api.ssm import get_secret
from resources.errors import ErrorResponse


Expand Down
2 changes: 0 additions & 2 deletions serverless.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,7 @@ provider:
OKDATA_PERMISSION_API_URL: ${ssm:/dataplatform/shared/api-gateway-url}/okdata-permission-api
TIMEZONE: "Europe/Oslo"
BACKUP_BUCKET_NAME: ${self:custom.backupBucket.${self:provider.stage}, self:custom.backupBucket.dev}
SLACK_MASKINPORTEN_API_ALERTS_WEBHOOK_URL: ${ssm:/dataplatform/slack/maskinporten-api-slack-webhook}
EMAIL_API_URL: ${ssm:/dataplatform/shared/email-api-url}
EMAIL_API_KEY: ${ssm:/dataplatform/shared/email-api-key}
KEY_ROTATION_GRACE_PERIOD_SECONDS: 300
KEY_DEFAULT_EXPIRATION_DAYS: 90
KEY_UNDER_ROTATION_EXPIRATION_DAYS: 7
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"cryptography>=41.0.4,<42",
"fastapi>=0.109.2",
"mangum>=0.12.4,<1",
"okdata-aws>=1.0.1,<2.0.0",
"okdata-aws>=2.1,<3",
"okdata-resource-auth>=0.1.4",
"pydantic>=1.10,<2",
"pyjwt>=2.7,<3",
Expand Down
5 changes: 5 additions & 0 deletions test/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ def initialize_parameter_store():
Value="supersecretpassword",
Type="SecureString",
)
ssm_client.put_parameter(
Name="/dataplatform/slack/maskinporten-api-slack-webhook",
Value="http://hooks.slack.arpa/services/123",
Type="SecureString",
)

for env in MaskinportenEnvironment:
ssm_client.put_parameter(
Expand Down
2 changes: 1 addition & 1 deletion test/maskinporten_api/test_ssm.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
from botocore.exceptions import ClientError
from freezegun import freeze_time
from moto.sts.models import STSBackend
from okdata.aws.ssm import get_secret

from maskinporten_api.keys import create_key
from maskinporten_api.ssm import (
AssumeRoleAccessDeniedError,
ForeignAccountSecretsClient,
get_secret,
)


Expand Down
2 changes: 1 addition & 1 deletion test/resources/test_maskinporten.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

CLIENTS_ENDPOINT = env_config("test").maskinporten_clients_endpoint
OKDATA_PERMISSION_API_URL = os.environ["OKDATA_PERMISSION_API_URL"]
SLACK_WEBHOOK_URL = os.environ["SLACK_MASKINPORTEN_API_ALERTS_WEBHOOK_URL"]
SLACK_WEBHOOK_URL = "http://hooks.slack.arpa/services/123"


def test_create_client(
Expand Down
1 change: 0 additions & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ setenv =
RESOURCE_SERVER_CLIENT_ID=some-resource-server
OKDATA_PERMISSION_API_URL = https://example.com/okdata-permission-api
BACKUP_BUCKET_NAME = backup-bucket
SLACK_MASKINPORTEN_API_ALERTS_WEBHOOK_URL = http://hooks.slack.arpa/services/123
TIMEZONE = Europe/Oslo
KEY_ROTATION_GRACE_PERIOD_SECONDS = 3
KEY_DEFAULT_EXPIRATION_DAYS = 90
Expand Down

0 comments on commit 06a5f9c

Please sign in to comment.