I have a serverless multi tenant application with one 'front end' in the forms of a MS Teams chat bot.
Each client company (tenant) receives an individual database bu the serverless application is shared among clients. The credentials for this database are stored in AWS Parameter store as a SecureString with the Tenant_ID (of the client's Azure AD) as parameter name.
All services (except the MS Teams chat bot) are secure in a VPC with no access from the outside.
The MS Teams chat bot service exposes a handler on POST /api/messages.
The "authentication" works a follows: when a message is received in the MS Teams chat bot the tenant_id of the user is extracted and is used to check if the tenant_id is registered within the parameter store. If not the chat bot returns a message that the client company needs to register first.
class TeamsAuthHelper:
async def check_if_tenant_is_registered(turn_context: TurnContext):
"""
Helper method that checks if the tenant_id exists as a parameter within the parameter store.
If the parameter exists, this implies that the user should be able to access our application.
Args:
tenant_id (str): The tenant ID of the user to be checked.
Returns:
[type]: Boolean
"""
try:
logger.debug("Checking if tenant is registered")
ssm_client = boto3.client("ssm")
response = ssm_client.get_parameter(
Name=turn_context.activity.channel_data["tenant"]["id"], WithDecryption=True)
if response is not None:
return True
return False
except ssm_client.exceptions.ParameterNotFound:
return False
except Exception as e:
logger.exception(
"An unregistered company tried to connect", extra={"exception": e})
await turn_context.send_activity("Your organisation seems to be not yet registered!")
Is this a secure way of doing it?