Skip to content

Commit

Permalink
use environmental variables for restricting access by ip address
Browse files Browse the repository at this point in the history
  • Loading branch information
pearl-truss committed Jan 26, 2024
1 parent 9e6ada6 commit 9247b17
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 18 deletions.
1 change: 1 addition & 0 deletions .envrc
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export DATABASE_URL='postgresql://postgres:shhhsecret@localhost:5432/postgres?sc
export EMAILER_MODE='LOCAL'
export LD_SDK_KEY='this-value-must-be-set-in-local'
export PARAMETER_STORE_MODE='LOCAL'
export ALLOWED_IP_ADDRESSES='127.0.0.1'

export REACT_APP_OTEL_COLLECTOR_URL='http://localhost:4318/v1/traces'
export REACT_APP_LD_CLIENT_ID='this-value-can-be-set-in-local-if-desired'
Expand Down
10 changes: 0 additions & 10 deletions services/app-api/serverless.yml
Original file line number Diff line number Diff line change
Expand Up @@ -188,16 +188,6 @@ functions:

graphql:
handler: src/handlers/apollo_gql.graphqlHandler
resourcePolicy:
- Effect: Deny
Principal: '*'
Action: execute-api:Invoke
Resource:
- execute-api:/*/*/*
Condition:
NotIpAddress:
aws:SourceIp:
- '123.123.123.123'

events:
- http:
Expand Down
2 changes: 1 addition & 1 deletion services/app-api/src/handlers/apollo_gql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ async function initializeGQLHandler(): Promise<Handler> {
if (stageName === undefined)
throw new Error('Configuration Error: stage is required')

if (parameterStoreMode !== 'LOCAL' && allowedIpAddresses === undefined)
if (allowedIpAddresses === undefined)
throw new Error('Configuration Error: allowed IP addresses is required')

if (!dbURL) {
Expand Down
22 changes: 15 additions & 7 deletions services/app-api/src/handlers/third_party_API_authorizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,17 @@ export const main: APIGatewayTokenAuthorizerHandler = async (
try {
// authentication step for validating JWT token
const userId = await jwtLib.userIDFromToken(authToken)
const parsedEvent = JSON.parse(JSON.stringify(event))
const host = parsedEvent.headers.Host
// host is formatted as ipaddress:port
// the following will remove the :port to leave just the ip address
const ipAddress = host.slice(0, host.indexOf(':'))

if (userId instanceof Error) {
const msg = 'Invalid auth token'
console.error(msg)

return generatePolicy(undefined, event)
return generatePolicy(undefined, event, ipAddress)
}

console.info({
Expand All @@ -34,29 +39,32 @@ export const main: APIGatewayTokenAuthorizerHandler = async (
status: 'SUCCESS',
})

return generatePolicy(userId, event)
return generatePolicy(userId, event, ipAddress)
} catch (err) {
console.error(
'unexpected exception attempting to validate authorization',
err
)
return generatePolicy(undefined, event)
return generatePolicy(undefined, event, undefined)
}
}

const generatePolicy = function (
userId: string | undefined,
event: APIGatewayTokenAuthorizerEvent
event: APIGatewayTokenAuthorizerEvent,
ipAddress: string | undefined
): APIGatewayAuthorizerResult {
// If the JWT is verified as valid, send an Allow policy
// this will allow the request to go through
// If the JWT is verified as valid, and the request comes from an allowed IP address
// send an Allow policy
// otherwise a Deny policy is returned which restricts access
const validIPAddress =
ipAddress && process.env.ALLOWED_IP_ADDRESSES?.includes(ipAddress)
const policyDocument: PolicyDocument = {
Version: '2012-10-17', // current version of the policy language
Statement: [
{
Action: 'execute-api:Invoke',
Effect: userId ? 'Allow' : 'Deny',
Effect: userId && validIPAddress ? 'Allow' : 'Deny',
Resource: event['methodArn'],
},
],
Expand Down

0 comments on commit 9247b17

Please sign in to comment.