项目作者: joyent

项目描述 :
策略语言和访问控制引擎
高级语言: JavaScript
项目地址: git://github.com/joyent/node-aperture.git
创建时间: 2013-10-14T17:54:50Z
项目社区:https://github.com/joyent/node-aperture

开源协议:Mozilla Public License 2.0

下载


Aperture

Aperture is an access control system with a flexible, human-readable policy
language, a parser that translates the language into serializable JSON, and an
evaluator that evaluates policies and a request’s context to determine whether
to allow or deny.

  1. var aperture = require('aperture');
  2. var parser = aperture.createParser({
  3. types: aperture.types,
  4. typeTable: {
  5. sourceip: 'ip',
  6. }
  7. });
  8. var policy = parser.parse('Fred can read *.js when sourceip = 10.0.0.0/8');
  9. var evaluator = aperture.createEvaluator({
  10. types: aperture.types,
  11. typeTable: {
  12. sourceip: 'ip',
  13. }
  14. });
  15. var context = {
  16. principal: 'Fred',
  17. action: 'read',
  18. resource: 'parser.example.js',
  19. conditions: {
  20. dirname: 'examples',
  21. sourceip: '10.0.0.1'
  22. }
  23. };
  24. var result = evaluator.evaluate(policy, context); // true

Usage

Both the parser and evaluator take the same set of options - a list of types
and a mapping from condition name to type name, both of which are used when
parsing or evaluating conditions. The list of types is used to validate
condition values when parsing and to perform operations when evaluating. The
type table is used to look up the type of a condition if one is not specified.

The parser can parse policy text and check for syntax errors without any type
information. If you pass in only types, condition values with explicit types
will be validated, but any condition values that require a type lookup will be
ignored. To validate both untyped and typed conditions, pass in types and
typeTable.

The types argument is required when creating an evaluator. The typeTable is
optional if every policy evaluated will only contain explicitly typed
conditions. Otherwise, pass in typeTable.

Policy Language

Write policies in subject-verb-object sentences, where subjects = principals,
actions = verbs, object = resources and other conditions follow as a phrase.
Language keywords (if, CAN, All, etc.) and condition operators (AND,
=, Like, etc.) are case-insensitive. Identifiers, including condition names,
type names, principals, actions, and resources are case-sensitive.

The basic format is <principals> CAN <actions> <resources> WHEN <conditions>.
Conditions are optional. For policies with implied principals or resources,
leave off those parts. The word starting the conditions clause can be when,
if , or where.

  • Fred can read
  • Fred can read /foo/bar when someCondition = 3
  • Fred can read where someCondition = 3
  • Can read if someCondition = 3

Principals, actions and resources

Principals, actions and resources can all be a single identifier or a list:

  • Fred
  • Fred and Bob
  • Fred, George and Bob
  • Fred, George, and Bob

The language supports exact strings, fuzzy strings, and regular expressions for
principal, action, and resource identifiers.

Exact strings need to be surrounded by double quotes only if they contain a
::, (, ), ,, or whitespace, or match a reserved word (in a
case-insensitive match).

You can use the * character to create fuzzy matches. This is equivalent to a
.* in a regular expression. Escape asterisks with \*.

  • ops_*
  • *.js
  • Ra*chel
  • \*Nsync

To specify a regular expression, append ::regex or ::regexp to a Javascript
regular expression literal.

  • /2013-0[1-6]-[0-3][0-9].log/::regex
  • /fred(dy)?/i::regex
  • /Ashl(y|ey|i|ie|ee|iy|eigh)/::regexp

Use a single *, or all, everything, or anything to match any identifier.

  • Fred can read *
  • All can read anything

Conditions

The conditions clause consists of a single expressions that will evaluate to
either true or false based on the context of a request. A basic condition has a
condition name, a type name, an operator, and a value. The condition name
should match the condition name as passed in as context when evaluating. The
type name is used to determine what logic should be used to compare values.

  • sourceip::ip = 10.0.0.1
  • statuscode::number > 200

Operators can be any string but must be an operator that the type supports (and
are case-insensitive).

  • dirname::string like /ops_.*/i

You can choose to leave off the type if you plan to use a type lookup table.
However, an explicit type will preempt any type lookups.

  • sourceip = 10.0.0.1
  • statuscode > 200

You can check for equality (= operator) in a list by using the in operator
on a comma separated list enclosed in parentheses.

  • requesttime::day in (Monday, Tuesday, Wednesday, Thursday, Friday)
  • sourceip::ip in (192.168.0.0/16, 10.0.0.0/8)

Join conditions together with and or or. Negate conditions with not.
Group conditions with parentheses.

  • sourceip = 10.0.0.1 OR sourceip = 192.168.1.1
  • time > 09:00:00 OR (day > Monday AND day < Friday)
  • NOT geoip from "North Korea"

Quoting

Principal, action, and resource identifiers, condition names, type names,
operators and values all do not need to be quoted unless they contain a ::,
(, ), ,, or whitespace, or match a reserved word (in a case-insensitive
match).

  • "Can" can read
  • "spid::::er-eyes" can see
  • "Sir Patrick" can act
  • sourceip::ip = "2001:db8::ff00:42:8329"

Identifiers with ::regex never need to be quoted.

  • /double::colons/::regex

Types

Aperture comes with a handful of types that cover many basic use cases.

  • date - full datetime, comparisons are based on UNIX epoch time in ms
  • day - days of the week, starting with 1 for Monday and 7 for Sunday
  • time - date-agnostic time type. comparisons based on ms from midnight
  • ip - ipv4 and ipv6 single addresses and range support
  • number - numbers.
  • string - strings with lexicographical comparison and like operator for
    regex matching