Sealing Policy Example

You can seal policy permissions at a particular realm. When you seal a policy, you lock the permissions at the declared realm.

Policy sealing example

For example, given the system-defined policy permissions for the job::/ realm:

job::/ {
  if (permit == all) {
    permit create, read, update, delete
    permit start, stop, map, ssh, promote, link, bind
  }
}

The standard admin role mapping policy is:

job::/ {
  if (role == "admin") { 
    permit all 
  }
}

But, if you wanted to only ensure that “permit all” only be applied at job::/ realm, you could seal the permission grant:

job::/{
  !seal permit all
  
  if (role == “admin”) {
    permit all
  }
}

As a result, the following policy will have no effect because the permit all grant has been sealed at the job::/ realm and cannot be applied to a descendent realm:

job::/sandbox/leroy {
  if (auth_server@apcera.me->name == "leroy") {
   { permit all }
}

Policy sealing details

Seal directives begin with "!seal" and are peers to rules. They can only appear within a realm definition and not within a rule; so they are not similar to claims. That is, the following is allowed:

job::/ {
    !seal claim

    if (...)  ...  // some rule
}

But not the following:

job::/  {
    if (...) {
        !seal foo  // Not allowed; only claims here, not seals
     }
}

A seal puts restrictions on all realms with a deeper level than the one where the seal is defined. In this context, deeper level means more a specific path. A seal with a claim name and no value prevents the deeper level from overriding that claim with its own value; the value from the shallower level will be used.

A seal with one or more values in addition to the claim name prevents the claim from being set to any of those values at the deeper level.

So for example, suppose this seal set exists at the root namespace / for jobs:

job::/ {
  !seal foo
  !seal bar one
  !seal bar two

  if (role == "dev")  {
    foo test
    bar one, two
  }
}

This example code says that policy at deeper levels (for example, job::/sandbox/jim) cannot set the "foo" claim at all. It can set the "bar" claim but not to the values "one" or "two".

Note that a given seal statement can only seal one value. For example, if you try to do the following, you get a parsing error:

job::/ {
  !seal foo
  !seal bar one, two

  if (role == "dev")  {
    foo test
    bar one, two
  }
}

In other words, you must explitly seal each permission grant that you want to protect:

job::/ {
  !seal permit create
  !seal permit update

  if (role == "dev")  {
    permit create, read, update, detele
  }
}

Understanding policy levels

To use policy sealing, you must understand policy levels.

The level is "deeper" for more specific paths. So /sandbox is level 1 and /sandbox/jim is level 2. Level comparisons are done independently for namespace vs. localname, with namespace taking priority. So the localname depth will only affect the result if the namespace depths are the same, for example: "job::/foo::bar" vs. "job::/foo::bar/ski".

Quota sealing example

The following policy example seals the total.package.size claim at the quota::/prod namespace:

quota::/prod {
  !seal max.package.size
  { max.package.size 200MB }
  { total.package.size 600MB }
}

As a result, in the following policy, only the total.package.size claim applies. The max.package.size claim does not apply (it is ignored) because it has been sealed at the /prod namespace.

quota::/prod/extend {
  { max.package.size 100MB }
  { total.package.size 300MB }
}

Permit sealing example

The following policy is sealed so that a rule attached further down in policy::/dev can't grant someone else a permit or ResType claim.

policy::/dev {
  !seal permit
  !seal ResType
  if (role == "dev" & ResType == job) {
    permit create, read, update, delete
  }
}

Thus, the following an attempt at an escalation, no permit should be allowed on this level for the permit claim type:

policy::/dev/hr {
  if (ldap@acme.com -> secGroup == XRE) {
    permit create
  }
}

Note that you could be more specific with your sealing if necessary or desired:

policy::/dev {
  !seal permit create
  !seal ResType job
  if (role == "dev" & ResType == job) {
    permit create, read, update, delete
  }
}