Smart Policies

burguesia edited this page Aug 14, 2016 · 16 revisions
Clone this wiki locally

Smart Policies


Smart Policies are scripts that receive notifications every time a watched file changes. Policies trigger actions such as emailing someone, reverting changes or shutting the system down.

Currently you can write policies in Javascript, CoffeeScript or IcedCoffeeScript.

Policies are Node.js packages downloaded from public git repositories. Anyone can take any available policy, fork it and improve it.

Policies are parameterizable. Each policy package can define customizable "fields" to suit different monitoring needs.

When the watcher starts, it runs every policy inside a sandboxed virtual machine. Such virtual machines run in the background, waiting the watched files to change.

Every time a watched file gets modified, the watcher generates a diff. Such diff is then sent to every one of the modified file's policies.

Ready-to-use policies

  • Mailer: send an email with the diff between the previous version of a file and the current one.
  • Backup: back up a file to a different location every time it gets modified.
  • Rollback: roll modified files back to the previous version.
  • Shutdown: shut the whole system down.
  • Stamper: embed the hash of each version of your monitored file into both the Bitcoin and the Ethereum blockchains creating an immutable audit trail
  • Zapier: connect your file events to a whole world of apps.
  • Do you have any interesting Smart Policy? File an issue and we will be happy to add it to this list.

Writing your own policies

Policy package structure

  • main.js / main.coffee / main.iced: Main entry point for the policy script.
  • package.json: Package manifest.
  • LICENSE: (optional)
  • README.md: (optional)

package.json example

{
  "name": "mailer-policy",
  "version": "0.0.1",
  "dependencies": {
    "email": "0.2.6"
  },
  "policy": {
    "language": "coffeescript",
    "params": {
      "from": {
        "type": "email",
        "label": "Sender address",
        "required": true,
        "tip": "The address to show as sender of the email."
      },
      "to": {
        "type": "email",
        "required": true,
        "tip": "The email will be sent to this address."
      },
      "format": {
        "type": "select",
        "label": "Format",
        "options": {     
          "plain": {
            "label": "Plain text"
          },
          "html": {
            "label": "HTML"
          }
        },
        "default": "plain"
      }
    },
    "defaultName": "Email notifications"
  }
}

The policy object is compulsory and must contain the language attribute. Possible values are javascript, coffeescript or icedcoffeescript.

The policy.params defines variables that you can customize when you attach the policy to a watched file. Their values are passed to the policy script's constructor.

The possible attributes under policy.params are:

Attribute Description Required
type Type of field to be shown when configuring this parameter. :white_check_mark:
label Label (show description) to be shown before this field. :white_check_mark:
tip Long description or advise on how to fill this field. :x:
default Default value for this attribute. :x:
required Whether this field is compulsory or not. :x:
options (Only if type is select) Object with available options and corresponding labels. E.g.:{"opt1" : "First option", "opt2" : "Second option"} :x:

Parameters field types

The allowed values for type are: text, checkbox, color, date, datetime, datetime-local, email, month, number, password, range, tel, time, url, week and select.

Policy script example

You can name your main class as you prefer as long as you export it by assigning it to module.exports.

Email = require('email').Email

module.exports = class Policy
  constructor : (params) ->
    @file = params.filename
    @from = params.from
    @to = params.to

  receiver : (changes, metadata) =>
    msg = new Email
      from: @from
      to: @to
      subject: """File "#{@file}" has been modified"""
      body: """File "#{@file}" has been modified.
        The changes are:
        #{JSON.stringify changes}
        """
    msg.send()

Receiver payload

The receiver method takes one single argument in the form of a Javascript object containing the following keys:

Key Description
diff The diff describing the changes occurred to a watched file (more info down below).
path The path of the file.
prev Previous version of the file (more info down below).
cur Current version of the file (more info down below).
diff array

The diff key receives an Array of different objects representing the diff between previous and current version of a modified file.

Changes example: (This depicts Alice trying to hide a root session and pretend to be Bob)

[
   {
      "type":"ellipsis",
      "size":439
   },
   {
      "type":"fill",
      "start":440,
      "lines":[
         "Jul 14 18:25:10 server: someone : TTY=pts/14 ; PWD=/home/alice ; USER=alice",
         "Jul 14 18:25:10 server: pam_unix: session opened for user alice by (uid=0)"
      ]
   },
   {
      "type":"rem",
      "start":442,
      "lines":[
         "Jul 14 18:25:10 server su[6249]: + /dev/pts/14 root:root",
         "Jul 14 18:25:10 server su[6249]: pam_unix(su:session): session opened for user root by (uid=0)",
      ]
   },
   {
      "type":"add",
      "start":444,
      "lines":[
         "Jul 14 18:25:10 server su[6249]: + /dev/pts/14 bob:bob",
         "Jul 14 18:25:10 server su[6249]: pam_unix(su:session): session opened for user bob by (uid=0)",
      ]
   }
]

Possible values for the type attribute are:

Value Description
ellipsis Represent a certain number of omitted lines which are irrelevant to the diff.
fill Contain a few lines surrounding the changes for helping to contextualize them.
add Contain added lines
rem Contain removed lines
prev and cur objects

prev brings information about previous version of the watched file (its state before modification).

cur brings information about current version of the watched file (its state after modification).

Both prev and cur are objects containing the following keys:

Key Description
time Timestamp.
content The file contents.