exframe-security
TypeScript icon, indicating that this package has built-in type declarations

5.5.0 • Public • Published

exFrame-Security

Environment Variables

AUTH0_AUDIENCE This environment variable is what is validated against the JWT token coming from Auth0. This must match each environment the token will be generated.

AUTH0_DOMAIN The domain is the Auth0 domain to the jwks well-known json service. This json service is used to validate the public key of the jwks RS256 token generated by Auth0

Express JWT Middleware

exframe-security allows microservices to secure the express router REST endpoints using this middleware. The user profile will be returned as a user property on the request object. The middleware will automatically return an HTTP error code 401 if the token is not valid or does not exist. The first is the user object from the id token passed with the request. The other is a csp string property that denotes the harmony-csp header passed with the request.

Implementation

const security = require('exframe-security');

route.get('/someroute', security.expressJwtMiddleware, (req, res, next) => {
  const user = req.user;
  next();
});

Redbird JWT Middleware

exframe-security allows for the Exzeo Redbird Node JS Proxy to secure the proxy endpoints using this middleware. The middleware will automatically return an HTTP error code 401 if the token is not valid or does not exist. The middleware will return two properties on the request. The first is the user object from the id token passed with the request. The other is a csp string property that denotes the harmony-csp header passed with the request.

Implementation

const security = require('exframe-security');

redbird.addResolver({ match: /^\/(.*)/, priority: 10 }).use(security.redbirdJwtMiddleware)...

Falcon Security

exframe-security allows microservices to retrieve a users profile from Falcon. The user profile from Falcon is different from the profile returned from the Auth0 ID token.

Implementation

const security = require('exframe-security');

route.get('/someroute', security.falconSecurityMiddleware, (req, res, next) => {
  const user = req.user;
  next();
});

RPC Implementation

const security = require('exframe-security');

rpcServer.func('doSomething', security.falconSecurityRpcMiddleware, async (context, args) => {
  const user = context.user;
  next();
});

Check Claim Security

exframe-security allows microservices to retrieve a users profile from Falcon as either middleware or a standalone function. The user profile from Falcon is different from the profile returned from the Auth0 ID token.

Optional Options Object

  • applicationToken - Configures exframe-security to pass the harmony-app-token to falcon for user authorization

Middleware Implementation

const security = require('exframe-security');

// Usage with REST requests (Express)
route.get('/someroute', security.checkClaimMiddleware({ applicationToken: 'XXXXXX' }).express, (req, res, next) => {
  const user = req.user;
  next();
});

// Usage with RPC
rpcServer.func('doSomething', security.checkClaimMiddleware({ applicationToken: 'XXXXXX' }).mq, async (context, args) => {
  const user = context.user;
  next();
});

Standalone Implementation

const security = require('exframe-security');

const user = await security.checkClaim(context, accessKey, { applicationToken: 'XXXXXX' });

Internal Tokens

Internal tokens may also be created with a valid access token for use with internal requests. This makes it easier for internal services to make requests against resources that may not be accessible for the authenticated user of the original request. See here to learn more about internal tokens.

An internal token may be created using the createInternalToken function of the user object returned by the express and mq check claim middleware.

const security = require('exframe-security');

rpcServer.func('doSomething', security.checkClaimMiddleware().mq, async (context, args) => {
  const user = context.user;
  const internalToken = await user.createInternalToken(context)
  next();
});

Resource Registration

exframe-security allows microservices to register securable resources with the security manager. The developer will need to add a .securityresourcesrc.js file that specifies each resource acted upon by the service on behalf of a user and the associated rights that may be granted a particular user. The developer will need to pass the instance of the mq module pre configured.

Implementation

const { resourceRegistrator } = require('exframe-security');

resourceRegistrator.registerResources({ mq });

Example .securityresourcesrc.js File

module.exports = {
  resources: [
    { code: 'SECURITY_RESOURCES', service: 'security-manager-service', name: 'Resources', uri: 'SecurityModule:SecurityResources', allowedRights: ['READ'] }
  ]
};

Resource Validation

exframe-security allows microservices to validate the requesting user has access to the securable resources they are trying to access. There are a pair of middleware functions to apply to either a Rest or RPC server, one to set up the list of resources a user has that are relevant to the service, and another to check if a user has a access to a specific resource/right pair.

setupUserSecurityResourceMiddleware

setupUserSecurityResourceMiddleware will apply the user resources as an array for the given service and provide a helper method for identifying whether the user has the desired access.

The following properties will be added to the request.user object by this middleware function:

  • userSecurityResources {object[]} - List of user resources used by the services
  • userSecurityResources[].right {string} - Access right granted for the resource (e.g. "READ")
  • userSecurityResources[].uri {string} - Resource identifier (e.g. "PolicyData:Transactions:*")
  • userSecurityResources[].mongoFilter {object} - Complete mongo query object with all resource conditions applied used to easily filter only data accessible to the user
    {
      $and: [
        { $or: [{ companyCode: 'TTIC', state: 'FL', product: 'HO3' }] },
        { agencyCode: { $in: [20001] } }
      ],
    }

Note: The RPC version of the function has a slightly different name: setupUserSecurityResourceRpcMiddleware Note: The "exframe-request" implementation of the function is named: setupContextUserSecurityResourceMiddleware

Express Example

const { setupUserSecurityResourceMiddleware } = require('exframe-security');

const securityResources = require('./.securityresourcesrc');
const userSecurityResourceMiddleware = setupUserSecurityResourceMiddleware(securityResources.resources);

app.use(userSecurityResourceMiddleware);

app.get('/', (request, response, next) => {
  if (!request.user.checkResourceAccess('RESOURCES:*', 'UPDATE')) {
    throw new Error('Forbidden');
  }

  next();
});

app.get('/resources', (request, response, next) => {
  const { mongoFilter } = request.user.userSecurityResources
    .find(resource => resource.uri === 'RESOURCES:*' && resource.right === 'READ');
  };

  // ... mongo query
});

RPC Example

const { setupUserSecurityResourceRpcMiddleware } = require('exframe-security');

const securityResources = require('./.securityresourcesrc');
const userSecurityResourceMiddleware = setupUserSecurityResourceRpcMiddleware(securityResources.resources);

rpcServer.use(userSecurityResourceMiddleware);

rpcServer.func('doSomething', async (context, args) => {
  if (!context.user.checkResourceAccess('RESOURCES:*', 'UPDATE')) {
    throw new Error('Forbidden');
  }

  // ... do something
});

rpcServer.func('accessSomething', async (context, args) => {
  const { mongoFilter } = request.user.userSecurityResources
    .find(resource => resource.uri === 'RESOURCES:*' && resource.right === 'READ');

  // ... mongo query
});

exframe-request Example

const exframeContext = require('exframe-context');
const { setupContextUserSecurityResourceMiddleware } = require('exframe-security');

const securityResources = require('./.securityresourcesrc');
const userContextSecurityResourceMiddleware = setupContextUserSecurityResourceMiddleware(securityResources.resources);

exframeContext.use(userContextSecurityResourceMiddleware);

checkResourceAccessMiddleware

The checkResourceAccessMiddleware provides two functions, express and rpc, that will return a middleware function to validate that a user has access to a given resource/right pair.

The middleware function has the following arguments:

  • resourceUri - The URI of the resource that the calling users will need access to
  • right - The right against the URI that the calling users will need access to

Express Example

const { checkResourceAccessMiddleware } = require('exframe-security');

const checkResourceAccess = checkResourceAccessMiddleware.express('Resources:*', 'READ');

app.get('/', checkResourceAccess, (request, response, next) => {
  next();
});

RPC Example

const { checkResourceAccessMiddleware } = require('exframe-security');

const checkResourceAccess = checkResourceAccessMiddleware.rpc('Resources:*', 'READ');

rpcServer.func('doSomething', checkResourceAccess, async (context, args) => {
  // ... do something
});

Readme

Keywords

none

Package Sidebar

Install

npm i exframe-security

Weekly Downloads

481

Version

5.5.0

License

ISC

Unpacked Size

152 kB

Total Files

60

Last publish

Collaborators

  • exzeodevops