SQL commands for security labels
- CREATE
- ALTER
- SHOW
- DROP
DEV.SCHEMA(ADMIN)=> CREATE SECURITY LEVEL conf VALUE 500;
CREATE SECURITY LEVEL
DEV.SCHEMA(ADMIN)=> CREATE SECURITY LEVEL greater VALUE 600;
CREATE SECURITY LEVEL
DEV.SCHEMA(ADMIN)=> CREATE SECURITY LEVEL secret VALUE 800;
CREATE SECURITY LEVEL
DEV.SCHEMA(ADMIN)=> SHOW SECURITY LEVEL ALL;
NAME | LEVEL
----------+--------
PUBLIC | 0
CONF | 500
GREATER | 600
SECRET | 800
OMNI | 32767
(5 rows)
Since SECRET has a higher value than CONF and GREATER, a user with SECRET can access CONF and GREATER levels, but a user with CONF or GREATER cannot access SECRET levels. A GREATER level can access a CONF level, and any other levels with lesser values.
DEV.SCHEMA(ADMIN)=> ALTER SECURITY LEVEL conf RENAME TO TOP_SECRET VALUE
1000;
ALTER SECURITY LEVEL
So now a user with the altered TOP_SECRET level can access SECRET levels, but a user with SECRET levels cannot access TOP_SECRET levels.
DEV.SCHEMA(ADMIN)=> CREATE CATEGORY super;
CREATE CATEGORY
DEV.SCHEMA(ADMIN)=> CREATE CATEGORY insider;
CREATE CATEGORY
DEV.SCHEMA(ADMIN)=> CREATE CATEGORY audit;
CREATE CATEGORY
DEV.SCHEMA(ADMIN)=> SHOW CATEGORY ALL;
NAME | ID
----------+--------
AUDIT | 3
INSIDER | 2
SUPER | 1
OMNI | 0
(4 rows)
DEV.SCHEMA(ADMIN)=> ALTER CATEGORY SUPER RENAME TO TOP_SECRET;
ALTER CATEGORY
DEV.SCHEMA(ADMIN)=> CREATE COHORT TOP;
CREATE COHORT
DEV.SCHEMA(ADMIN)=> CREATE COHORT SALES IN COHORT TOP;
CREATE COHORT
DEV.SCHEMA(ADMIN)=> CREATE COHORT "NA" in COHORT sales;
CREATE COHORT
DEV.SCHEMA(ADMIN)=> CREATE COHORT "EUROPE" in COHORT sales;
CREATE COHORT
DEV.SCHEMA(ADMIN)=> CREATE COHORT "Asia" in COHORT sales;
CREATE COHORT
DEV.SCHEMA(ADMIN)=> CREATE COHORT DIST in COHORT top;
CREATE COHORT
DEV.SCHEMA(ADMIN)=> CREATE COHORT ENG in COHORT "Europe";
CREATE COHORT
DEV.SCHEMA(ADMIN)=> CREATE COHORT FRA in COHORT "Europe";
CREATE COHORT
DEV.SCHEMA(ADMIN)=> CREATE COHORT GER in COHORT "Europe";
CREATE COHORT
DEV.SCHEMA(ADMIN)=> CREATE COHORT NE in COHORT dist;
CREATE COHORT
DEV.SCHEMA(ADMIN)=> SHOW COHORT ALL;
NAME | ID | CLOSURE
--------+----+----------------------------------------------------
Asia | 5 | "Asia"
DIST | 6 | DIST,NE
ENG | 8 | ENG
Europe | 4 | "Europe",ENG,FRA,GER
FRA | 9 | FRA
GER | 10 | GER
NA | 3 | "NA"
NE | 7 | NE
OMNI | 0 |
SALES | 2 | SALES,"NA","Europe","Asia",ENG,FRA,GER
TOP | 1 | TOP,SALES,"NA","Europe","Asia",DIST,NE,ENG,FRA,GER
(11 rows)
The hierarchy shows that the cohort at the top can access all the cohorts beneath it. DIST cannot access SALES cohorts (both are “siblings” of TOP), and vice versa. NA, EUROPE, and ASIA cannot access NE and vice versa.
- The label level must be less than or equal to the profile level.
- All members of the label category must be members of the profile. The user must have all data categories.
- At least one member of the table row cohort must also be a member of the profile.
DEV.SCHEMA(ADMIN)=> CREATE USER MARY PASSWORD 'abcd' SECURITY LABEL 'secret:
blue';
CREATE USER
The absence of a specified dimension does not have an identifier, and is treated as missing. The missing state is used to decide whether to evaluate the access check.
If the label on a row is missing, the system ignores the user state and allows access. If the user label is missing, it is treated as NONE.
User profile | Security label | Result |
---|---|---|
Missing | Missing | Allow access |
Missing | Specified | Access not allowed |
Specified | Missing | Allow access |
Specified | Specified | The user must have all categories that the table row has. The user can have more categories. |
User profile | Security label | Result |
---|---|---|
Missing | Missing | Allow access |
Missing | Specified | Access not allowed |
Specified | Missing | Allow access |
Specified | Specified | The user must have at least one cohort in common with the table row. Both the user and the table row can have other cohorts. |
DEV.SCHEMA(ADMIN)=> CREATE USER GRETA SECURITY LABEL 'SECRET : INSIDER, AUDIT
: DIST, Europe, Asia';
CREATE USER
Level | Category (all-of) | Cohort (any-of) | Can access |
---|---|---|---|
CONF | INSIDER | Asia | Yes. |
CONF | INSIDER | SALES | No. User is restricted because none of the cohorts of user is SALES. |
AUDIT | OMNI | Asia | No. User is restricted because OMNI equals all categories, and INSIDER and AUDIT are a subset of the all-of categories. |
GREATER | AUDIT | FRA | Yes. FRA belongs to cohort Europe. |
TOP_SECRET | SUPER | GER | No. Level is too low and user ID does not have SUPER as a category. |
- The maximum of the levels.
- The union of the all-of tag sets (categories).
- The intersection of the any-of tag sets (cohorts).
The system does not automatically calculate combinations of labels. You can define functions and aggregates to enforce rules.
- combine_label(label1, label2)
This is a scalar function that combines two or more labels and returns the most restrictive combination.
- max_label(label)
This is an aggregate function that combines a set of labels and returns a single, most restrictive label.
DEV.SCHEMA(ADMIN)=> SELECT combine_label('secret: blue:psg', 'public: green:
qa');
COMBINE_LABEL
------------------------
SECRET:GREEN,BLUE:NONE
(1 row)
To label query results or use for CTAS, you may combine labels with max_label and combine_label, which calculates the most restrictive label. Joins have no label, just the result.