🎭

Authorization and role-based access

Knowing what you can do is serious business.
You'll often see tutorials and such talking about authentication, which is about how we can verify that a person really is the person they claim to be. This tends to be mostly a technical exercise.
​Authorization, on the other hand, is knowing what this person is allowed to do.
Only trivial systems will require no authorization, so prepare to think about how you want your model to work and how to construct your permission sets. Rather than being a technical concern, this becomes more logical than anything else.
Authentication is entirely out of scope here, whereas trivial authorization is in scope.
🎯 Example 1: In serverless.yml (lines 60-62) we define an authorizer function, located at src/FeatureToggles/controllers/AuthController.ts. Then on lines 70-74, we attach it to the FakeUser function. Now, the authorizer will run before the FakeUser function when called.
serverless.yml
functions:
Authorizer:
handler: src/FeatureToggles/controllers/AuthController.handler
description: ${self:service} authorizer
FakeUser:
handler: src/FakeUser/controllers/FakeUserController.handler
description: Fake user
events:
- http:
method: GET
path: /fakeUser
authorizer:
name: Authorizer
resultTtlInSeconds: 30 # See: https://forum.serverless.com/t/api-gateway-custom-authorizer-caching-problems/4695
identitySource: method.request.header.Authorization
type: request
🎯 Example 2: In our application we use a handcrafted RBAC (role-based access control) to attach a user group to each of the users. The user group is added as a flag in the subsequent call to the actual service.
src/FeatureToggles/usecases/getUserFeatureToggles.ts
/**
* @description Get user's authorization level keyed for their name. Fallback is "standard" features.
*/
function getUserAuthorizationLevel(user: string): string {
const authorizationLevel = userPermissions[user];
if (!authorizationLevel) return "standard";
else return authorizationLevel;
}
src/FeatureToggles/config/userPermissions.ts
export const userPermissions: Record<string, UserGroup> = {
"[email protected]": "error",
"[email protected]": "legacy",
"[email protected]": "beta",
"[email protected]": "standard",
"[email protected]": "devNewFeature",
"[email protected]any.com": "qa",
};
For more full-fledged implementations, consider tools like Oso to authorize on the overall "access level". See for example this demo using a similar serverless stack, or the plain quick start version.