Enforcement Mode vs. Monitor Mode

Intrinsic enforces your policies by default; if any code tries to perform an operation that isn't allowed by your policies, then that operation will be blocked, the violation will be logged, and an error will be thrown to be handled by your normal error handlers.

On the other hand, monitor mode lets you see if any policies are being violated, without blocking these operations causing the violation. All policy violations are logged, but the normally disallowed operations will run and no errors will be propagated. Monitor mode can be useful for building an initial set of policies.

Enabling Monitor Mode

To enable monitor mode, modify your intrinsic.js file (or wherever you keep your policies) and in the method chain add a call to .enableMonitorMode(). Here's an example of enabling monitor mode:

const intrinsic = require('@intrinsic/intrinsic');
intrinsic(__filename)
  .enableMonitorMode() // This line enables monitor mode
  .loadPolicies('./intrinsic-policy.js')
  .run('./server.js');

Once a violation does occur you will see a message resembling the following in your application's stderr output, if you're using Intrinsic for Node.js, or in Amazon CloudWatch Logs, if you're using Intrinsic for Lambda:

[INTRINSIC (MONITOR)] OutboundHttpPolicyViolation: POLICY_VIOLATION sb: "0"
  | [GET] http://api.intrinsic.com/ not in outbound http whitelist

In this case we need to add the following outbound HTTP policy to allow calls to http://api.intrinsic.com:

(policy) => {
  policy.outboundHttp.allowGet('http://api.intrinsic.com');
}

Monitor Mode isn't a Silver Bullet

Keep in mind that monitor mode is merely a supplement to writing correct policies. It's important to be very aware of the necessary capabilities of your application and make sure that the policies you create are intentional. If you do use monitor mode to help write policies you should ensure you've tested every capability of your application.

Consider the situation where your application has a conditional statement and can make two outbound HTTP requests. If you only test the first condition while writing policies and not the second, you will likely find that the second condition fails when run in production as Intrinsic would block the non-whitelisted outbound request.

Also consider that monitor mode simply writes the exact violations as they occur. For example, an application may make requests to a third party API, passing along a username string which is used in the requested URL. Perhaps while testing your application with a single username only the following request is made:

GET https://api.github.com/users/GitStarInc

Of course, writing a policy strictly based on the output of monitor mode could be disastrous. Consider the following policy:

(policy) => {
  policy.outboundHttp.allowGet('https://api.github.com/users/GitStarInc');
}

Once a request for a username other than GitStarInc has been made, the request would fail once the application switches to enforcement mode. This is the kind of problem you might not encounter until running your policies in production. Chances are your application would need this less-strict policy:

(policy) => {
  policy.outboundHttp.allowGet('https://api.github.com/users/*');
}

For this reason we recommend using monitor mode for a starting point, looking through your code to see the various I/O it performs, and even consider running your application in monitor mode while in production and iteratively building your policies based on the real-world violations.