You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@accumulo.apache.org by GitBox <gi...@apache.org> on 2018/11/14 22:30:36 UTC

[GitHub] mikewalch closed pull request #129: Updated Security documentation

mikewalch closed pull request #129: Updated Security documentation
URL: https://github.com/apache/accumulo-website/pull/129
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/_docs-2/development/mapreduce.md b/_docs-2/development/mapreduce.md
index 60285313..0adb6494 100644
--- a/_docs-2/development/mapreduce.md
+++ b/_docs-2/development/mapreduce.md
@@ -54,8 +54,8 @@ The following code shows how to set up Accumulo
 
 ```java
 Job job = new Job(getConf());
-ClientInfo info = Accumulo.newClient().forInstance("myinstance","zoo1,zoo2")
-                        .usingPassword("user", "passwd").info()
+ClientInfo info = Accumulo.newClient().to("myinstance","zoo1,zoo2")
+                        .as("user", "passwd").info()
 AccumuloInputFormat.setClientInfo(job, info);
 AccumuloInputFormat.setInputTableName(job, table);
 AccumuloInputFormat.setScanAuthorizations(job, new Authorizations());
@@ -154,8 +154,8 @@ class MyMapper extends Mapper<Key,Value,WritableComparable,Writable> {
 ## AccumuloOutputFormat options
 
 ```java
-ClientInfo info = Accumulo.newClient().forInstance("myinstance","zoo1,zoo2")
-                        .usingPassword("user", "passwd").info()
+ClientInfo info = Accumulo.newClient().to("myinstance","zoo1,zoo2")
+                        .as("user", "passwd").info()
 AccumuloOutputFormat.setClientInfo(job, info);
 AccumuloOutputFormat.setDefaultTableName(job, "mytable");
 ```
diff --git a/_docs-2/getting-started/clients.md b/_docs-2/getting-started/clients.md
index b6e4e316..19ae2993 100644
--- a/_docs-2/getting-started/clients.md
+++ b/_docs-2/getting-started/clients.md
@@ -35,13 +35,13 @@ of the following methods:
    of the tarball distribution):
     ```java
     AccumuloClient client = Accumulo.newClient()
-                        .usingProperties("/path/to/accumulo-client.properties").build();
+                              .from("/path/to/accumulo-client.properties").build();
     ```
 1. Using the builder methods of [AccumuloClient]:
     ```java
     AccumuloClient client = Accumulo.newClient()
-                        .forInstance("myinstance", "zookeeper1,zookeeper2")
-                        .usingPassword("myuser", "mypassword").build();
+                              .to("myinstance", "zookeeper1,zookeeper2")
+                              .as("myuser", "mypassword").build();
     ```
 1. Using a Java Properties object.
     ```java
@@ -51,7 +51,7 @@ of the following methods:
     props.put("auth.type", "password")
     props.put("auth.principal", "myuser")
     props.put("auth.token", "mypassword")
-    AccumuloClient client = Accumulo.newClient().usingProperties(props).build();
+    AccumuloClient client = Accumulo.newClient().from(props).build();
     ```
 
 If a `accumulo-client.properties` file or a Java Properties object is used to create a [AccumuloClient], the following
@@ -97,9 +97,8 @@ implementations of [AuthenticationToken] below:
 
     ```java
     KerberosToken token = new KerberosToken();
-    AccumuloClient client = Accumulo.newClient()
-                        .forInstance("myinstance", "zookeeper1,zookeper2")
-                        .usingToken(token.getPrincipal(), token).build();
+    AccumuloClient client = Accumulo.newClient().to("myinstance", "zookeeper1,zookeper2")
+                              .as(token.getPrincipal(), token).build();
     ```
 
 ## Writing Data
diff --git a/_docs-2/getting-started/features.md b/_docs-2/getting-started/features.md
index bf4027d5..9746f2de 100644
--- a/_docs-2/getting-started/features.md
+++ b/_docs-2/getting-started/features.md
@@ -22,7 +22,7 @@ written to disk) that happen in the tablet server.
 
 ### Security labels
 
-Accumulo Keys can contain a [security label]({% durl security/labels %})
+Accumulo Keys can contain a [security label]({% durl security/authorizations#security-labels %})
 (called a Column Visibility) that enables expressive cell-level access control.
 Authorizations are passed with each query to control what data is returned to the user.
 Column visibilities support boolean `AND` and `OR` combinations of arbitrary strings (such
diff --git a/_docs-2/getting-started/table_configuration.md b/_docs-2/getting-started/table_configuration.md
index 57e7aec2..df6156f8 100644
--- a/_docs-2/getting-started/table_configuration.md
+++ b/_docs-2/getting-started/table_configuration.md
@@ -35,7 +35,7 @@ programmatically as follows:
 
 ```java
 AccumuloClient client = Accumulo.newClient()
-                        .usingProperties("/path/to/accumulo-client.properties").build();
+                          .from("/path/to/accumulo-client.properties").build();
 
 HashMap<String,Set<Text>> localityGroups = new HashMap<String, Set<Text>>();
 
diff --git a/_docs-2/getting-started/table_design.md b/_docs-2/getting-started/table_design.md
index 0d10e888..e03d7b3c 100644
--- a/_docs-2/getting-started/table_design.md
+++ b/_docs-2/getting-started/table_design.md
@@ -34,7 +34,7 @@ userid as the range of a scanner and fetching specific columns:
 
 ```java
 AccumuloClient client = Accumulo.newClient()
-                        .usingProperties("/path/to/accumulo-client.properties").build();
+                          .from("/path/to/accumulo-client.properties").build();
 Range r = new Range(userid, userid); // single row
 Scanner s = client.createScanner("userdata", auths);
 s.setRange(r);
diff --git a/_docs-2/security/authentication.md b/_docs-2/security/authentication.md
new file mode 100644
index 00000000..549c0317
--- /dev/null
+++ b/_docs-2/security/authentication.md
@@ -0,0 +1,92 @@
+---
+title: Authentication
+category: security
+order: 2
+---
+
+Accumulo has authentication to verify the identity of users.
+
+## Configuration
+
+Accumulo can be configured to use different authentication methods:
+
+| Method  | Setting for {% plink instance.security.authenticator %} |
+|---------|---------|
+| Password **(default)** | {% jlink -f org.apache.accumulo.server.security.handler.ZKAuthenticator %} |
+| [Kerberos]({% durl security/kerberos %}) | {% jlink -f org.apache.accumulo.server.security.handler.KerberosAuthenticator %} |
+
+All authentication methods implement [Authenticator]. The default (password-based) implementation method is described in this document.
+
+## Root user
+
+When [Accumulo is initialized]({% durl getting-started/quick-install#initialization %}), a `root` user is created and given
+a password.  This `root` user is used to create other users. 
+
+## Creating users
+
+Users can be created in the shell:
+
+```
+root@uno> createuser bob
+Enter new password for 'bob': ****
+Please confirm new password for 'bob': ****
+```
+
+In the Java API using [SecurityOperations]:
+
+```java
+client.securityOperations().createLocalUser("bob", new PasswordToken("pass"));
+```
+
+## Authenticating users
+
+Users are authenticated when they [create an Accumulo client]({% durl getting-started/clients#creating-an-accumulo-client %})
+or when the log in to the [Accumulo shell]({% durl getting-started/shell %}).
+
+Authentication can also be tested in the shell:
+
+```
+root@myinstance mytable> authenticate bob
+Enter current password for 'bob': ****
+Valid
+```
+
+In the Java API using [SecurityOperations]:
+
+```java
+boolean valid = client.securityOperations().authenticateUser("bob", new PasswordToken("pass"));
+```
+
+## Changing user passwords
+
+A user's password can changed be in the shell:
+
+```
+root@uno> passwd -u bob
+Enter current password for 'root': ******
+Enter new password for 'bob': ***
+```
+
+In the Java API using [SecurityOperations]:
+
+```java
+client.securityOperations().changeLocalUserPassword("bob", new PasswordToken("pass"));
+```
+
+## Removing users
+
+Users can be removed in the shell:
+
+```
+root@uno> dropuser bob
+dropuser { bob } (yes|no)? yes
+```
+
+In the Java API using [SecurityOperations]:
+
+```java
+client.securityOperations().dropLocalUser("bob");
+```
+
+[Authenticator]: {% jurl org.apache.accumulo.server.security.handler.Authenticator %}
+[SecurityOperations]: {% jurl org.apache.accumulo.core.client.admin.SecurityOperations %}
diff --git a/_docs-2/security/labels.md b/_docs-2/security/authorizations.md
similarity index 68%
rename from _docs-2/security/labels.md
rename to _docs-2/security/authorizations.md
index e5414028..5d3b4563 100644
--- a/_docs-2/security/labels.md
+++ b/_docs-2/security/authorizations.md
@@ -1,35 +1,40 @@
 ---
-title: Security Labels
+title: Authorizations
 category: security
-order: 2
+order: 4
 ---
 
+In Accumulo, data is written with [security labels] that limit access to only users with the proper
+[authorizations][auths].
+
+## Configuration
+
+Accumulo's [Authorizor] is configured by setting {% plink instance.security.authorizer %}. The default
+authorizor is described below.
+
+## Security Labels
+
 Every [Key]-[Value] pair in Accumulo has its own security label, stored under the column visibility
 element of the key, which is used to determine whether a given user meets the security
 requirements to read the value. This enables data of various security levels to be stored
 within the same row, and users of varying degrees of access to query the same table, while
 preserving data confidentiality.
 
-## Security Label Expressions
+### Writing labeled data
 
-When mutations are applied, users can specify a security label for each value. This is
-done as the [Mutation] is created by passing a [ColumnVisibility] object to the put()
-method:
+When [writing data to Accumulo]({% durl getting-started/clients#writing-data %}), users can
+specify a security label for each value by passing a [ColumnVisibilty] to the [Mutation].
 
 ```java
-Text rowID = new Text("row1");
-Text colFam = new Text("myColFam");
-Text colQual = new Text("myColQual");
-ColumnVisibility colVis = new ColumnVisibility("public");
-long timestamp = System.currentTimeMillis();
-
-Value value = new Value("myValue");
-
-Mutation mutation = new Mutation(rowID);
-mutation.put(colFam, colQual, colVis, timestamp, value);
+try (BatchWriter writer = client.createBatchWriter("employees")) {
+  Mutation mut = new Mutation("employee1");
+  mut.at().family("pay").qualifier("salary").visibility("payroll").value("50000");
+  mut.at().family("pay").qualifier("period").visibility("public").value("monthly");
+  writer.addMutation(mut)
+}
 ```
 
-## Security Label Expression Syntax
+### Security Label Expression Syntax
 
 Security labels consist of a set of user-defined tokens that are required to read the
 value the label is associated with. The set of tokens required can be specified using
@@ -85,7 +90,7 @@ Authorizations auths = new Authorizations("admin","system");
 Scanner s = client.createScanner("table", auths);
 ```
 
-## User Authorizations
+### User Authorizations
 
 Each Accumulo user has a set of associated security labels. To manipulate these in
 the [Accumulo shell][shell], use the `setuaths` and `getauths` commands. They can be
@@ -108,6 +113,24 @@ Any user with the alter table permission can add or remove this constraint.
 This constraint is not applied to bulk imported data, if this a concern then
 disable the bulk import permission.
 
+### Advanced Authorizations Handling
+
+For applications serving many users, it is not expected that an Accumulo user
+will be created for each application user. In this case an Accumulo user with
+all authorizations needed by any of the applications users must be created. To
+service queries, the application should create a scanner with the application
+user's authorizations. These authorizations could be obtained from a trusted 3rd
+party.
+
+Often production systems will integrate with Public-Key Infrastructure (PKI) and
+designate client code within the query layer to negotiate with PKI servers in order
+to authenticate users and retrieve their authorization tokens (credentials). This
+requires users to specify only the information necessary to authenticate themselves
+to the system. Once user identity is established, their credentials can be accessed by
+the client code and passed to Accumulo outside of the reach of the user.
+
+[security labels]: {% durl security/authorizations#security-labels %}
+[auths]: {% durl security/authorizations#authorizations %}
 [shell]: {% durl getting-started/shell %}
 [Key]: {% jurl org.apache.accumulo.core.data.Key %}
 [Value]: {% jurl org.apache.accumulo.core.data.Value %}
@@ -121,3 +144,4 @@ disable the bulk import permission.
 [Instance]: {% jurl org.apache.accumulo.core.client.Instance %}
 [AuthenticationToken]: {% jurl org.apache.accumulo.core.client.security.tokens.AuthenticationToken %}
 [PasswordToken]: {% jurl org.apache.accumulo.core.client.security.tokens.PasswordToken %}
+[Authorizor]: {% jurl org.apache.accumulo.server.security.handler.Authorizor %}
diff --git a/_docs-2/security/kerberos.md b/_docs-2/security/kerberos.md
index 2253449a..716f630b 100644
--- a/_docs-2/security/kerberos.md
+++ b/_docs-2/security/kerberos.md
@@ -1,7 +1,7 @@
 ---
 title: Kerberos
 category: security
-order: 5
+order: 7
 ---
 
 ## Overview
@@ -139,20 +139,20 @@ all Accumulo servers must share the same instance and realm principal components
 A number of properties need to be changed to account to properly configure servers
 in `accumulo.properties`.
 
-|Key | Default Value | Description
+|Key | Suggested Value | Description
 |----|---------------|-------------
-| general.kerberos.keytab | /etc/security/keytabs/accumulo.service.keytab | The path to the keytab for Accumulo on local filesystem. Change the value to the actual path on your system.
-| general.kerberos.principal | accumulo/_HOST@REALM | The Kerberos principal for Accumulo, needs to match the keytab. "_HOST" can be used instead of the actual hostname in the principal and will be automatically expanded to the current FQDN which reduces the configuration file burden.
-|instance.rpc.sasl.enabled | true | Enables SASL for the Thrift Servers (supports GSSAPI)
-|rpc.sasl.qop | auth | One of "auth", "auth-int", or "auth-conf". These map to the SASL defined properties for quality of protection. "auth" is authentication only. "auth-int" is authentication and data integrity. "auth-conf" is authentication, data integrity and confidentiality.
-|instance.security.authenticator | org.apache.accumulo.server.security.handler.KerberosAuthenticator | Configures Accumulo to use the Kerberos principal as the Accumulo username/principal
-|instance.security.authorizor | org.apache.accumulo.server.security.handler.KerberosAuthorizor | Configures Accumulo to use the Kerberos principal for authorization purposes
-|instance.security.permissionHandler | org.apache.accumulo.server.security.handler.KerberosPermissionHandler| Configures Accumulo to use the Kerberos principal for permission purposes
-|trace.token.type | org.apache.accumulo.core.client.security.tokens.KerberosToken | Configures the Accumulo Tracer to use the KerberosToken for authentication when serializing traces to the trace table.
-|trace.user | accumulo/_HOST@REALM | The tracer process needs valid credentials to serialize traces to Accumulo. While the other server processes are creating a SystemToken from the provided keytab and principal, we can still use a normal KerberosToken and the same keytab/principal to serialize traces. Like non-Kerberized instances, the table must be created and permissions granted to the trace.user. The same `_HOST` replacement is performed on this value, substituted the FQDN for `_HOST`.
-|trace.token.property.keytab | | You can optionally specify the path to a keytab file for the principal given in the `trace.user` property. If you don't set this path, it will default to the value given in `general.kerberos.principal`.
-|general.delegation.token.lifetime | 7d | The length of time that the server-side secret used to create delegation tokens is valid. After a server-side secret expires, a delegation token created with that secret is no longer valid.
-|general.delegation.token.update.interval| 1d | The frequency in which new server-side secrets should be generated to create delegation tokens for clients. Generating new secrets reduces the likelihood of cryptographic attacks.
+| {% plink general.kerberos.keytab %} | /etc/security/keytabs/accumulo.service.keytab | The path to the keytab for Accumulo on local filesystem. Change the value to the actual path on your system.
+| {% plink general.kerberos.principal %} | accumulo/_HOST@REALM | The Kerberos principal for Accumulo, needs to match the keytab. "_HOST" can be used instead of the actual hostname in the principal and will be automatically expanded to the current FQDN which reduces the configuration file burden.
+| {% plink instance.rpc.sasl.enabled %} | true | Enables SASL for the Thrift Servers (supports GSSAPI)
+| {% plink rpc.sasl.qop %} | auth | One of "auth", "auth-int", or "auth-conf". These map to the SASL defined properties for quality of protection. "auth" is authentication only. "auth-int" is authentication and data integrity. "auth-conf" is authentication, data integrity and confidentiality.
+| {% plink instance.security.authenticator %} | {% jlink -f org.apache.accumulo.server.security.handler.KerberosAuthenticator %} | Configures Accumulo to use the Kerberos principal as the Accumulo username/principal
+| {% plink instance.security.authorizor %} | {% jlink -f org.apache.accumulo.server.security.handler.KerberosAuthorizor %} | Configures Accumulo to use the Kerberos principal for authorization purposes
+| {% plink instance.security.permissionHandler %} | {% jlink -f org.apache.accumulo.server.security.handler.KerberosPermissionHandler %} | Configures Accumulo to use the Kerberos principal for permission purposes
+| {% plink trace.token.type %} | {% jlink -f org.apache.accumulo.core.client.security.tokens.KerberosToken %} | Configures the Accumulo Tracer to use the [KerberosToken] for authentication when serializing traces to the trace table.
+| {% plink trace.user %} | accumulo/_HOST@REALM | The tracer process needs valid credentials to serialize traces to Accumulo. While the other server processes are creating a SystemToken from the provided keytab and principal, we can still use a normal [KerberosToken] and the same keytab/principal to serialize traces. Like non-Kerberized instances, the table must be created and permissions granted to the trace.user. The same `_HOST` replacement is performed on this value, substituted the FQDN for `_HOST`.
+| trace.token.property.keytab | | You can optionally specify the path to a keytab file for the principal given in the `trace.user` property. If you don't set this path, it will default to the value given in `general.kerberos.principal`.
+| {% plink general.delegation.token.lifetime %} | 7d | The length of time that the server-side secret used to create delegation tokens is valid. After a server-side secret expires, a delegation token created with that secret is no longer valid.
+| {% plink general.delegation.token.update.interval %} | 1d | The frequency in which new server-side secrets should be generated to create delegation tokens for clients. Generating new secrets reduces the likelihood of cryptographic attacks.
 
 Although it should be a prerequisite, it is ever important that you have DNS properly
 configured for your nodes and that Accumulo is configured to use the FQDN. It
@@ -168,7 +168,7 @@ by adding the JVM system property `-Djava.security.krb5.conf=/path/to/other/krb5
 
 #### KerberosAuthenticator
 
-The `KerberosAuthenticator` is an implementation of the pluggable security interfaces
+The [KerberosAuthenticator] is an implementation of the pluggable security interfaces
 that Accumulo provides. It builds on top of what the default ZooKeeper-based implementation,
 but removes the need to create user accounts with passwords in Accumulo for clients. As
 long as a client has a valid Kerberos identity, they can connect to and interact with
@@ -378,17 +378,17 @@ $
 
 #### DelegationTokens with MapReduce
 
-To use DelegationTokens in a custom MapReduce job, the user should create an `AccumuloClient`
-using a `KerberosToken` and use it to call `SecurityOperations.getDelegationToken`. The
-`DelegationToken` that is created can then be used to create a new client using this
-delegation token.  The `ClientInfo` object from this client can be passed into the MapReduce
+To use DelegationTokens in a custom MapReduce job, the user should create an [AccumuloClient]
+using a [KerberosToken] and use it to call `SecurityOperations.getDelegationToken`. The
+[DelegationToken] that is created can then be used to create a new client using this
+delegation token.  The [ClientInfo] object from this client can be passed into the MapReduce
 job. It is expected that the user launching the MapReduce job is already logged in via Kerberos
 via a keytab or via a locally-cached Kerberos ticket-granting-ticket (TGT).
 
 ```java
 KerberosToken kt = new KerberosToken();
-AccumuloClient client = Accumulo.newClient().forInstance("myinstance", "zoo1,zoo2")
-                .usingToken(principal, kt).build();
+AccumuloClient client = Accumulo.newClient().to("myinstance", "zoo1,zoo2")
+                          .as(principal, kt).build();
 DelegationToken dt = client.securityOperations().getDelegationToken();
 AccumuloClient client2 = client.changeUser(principal, dt);
 ClientInfo info2 = client2.info();
@@ -404,7 +404,7 @@ Users must have the `DELEGATION_TOKEN` system permission to call the `getDelegat
 method. The obtained delegation token is only valid for the requesting user for a period
 of time dependent on Accumulo's configuration (`general.delegation.token.lifetime`).
 
-For the duration of validity of the `DelegationToken`, the user *must* take the necessary precautions
+For the duration of validity of the [DelegationToken], the user *must* take the necessary precautions
 to protect the `DelegationToken` from prying eyes as it can be used by any user on any host to impersonate
 the user who requested the `DelegationToken`. YARN ensures that passing the delegation token from the client
 JVM to each YARN task is secure, even in multi-tenant instances.
@@ -571,3 +571,8 @@ Ensure you have set `trace.token.property.keytab` to point to a keytab for the p
 [sasl.enabled]: {% purl -c sasl.enabled %}
 [sasl.qop]: {% purl -c sasl.qop %}
 [sasl.kerberos.server.primary]: {% purl -c sasl.kerberos.server.primary %}
+[KerberosAuthenticator]: {% jurl org.apache.accumulo.server.security.handler.KerberosAuthenticator %}
+[AccumuloClient]: {% jurl org.apache.accumulo.core.client.AccumuloClient %}
+[KerberosToken]: {% jurl org.apache.accumulo.core.client.security.tokens.KerberosToken %}
+[DelegationToken]: {% jurl org.apache.accumulo.core.client.security.tokens.DelegationToken %}
+[ClientInfo]: {% jurl org.apache.accumulo.core.client.ClientInfo %}
diff --git a/_docs-2/security/on-disk-encryption.md b/_docs-2/security/on-disk-encryption.md
index a060d6c6..e7be37bf 100644
--- a/_docs-2/security/on-disk-encryption.md
+++ b/_docs-2/security/on-disk-encryption.md
@@ -1,7 +1,7 @@
 ---
 title: On Disk Encryption
 category: security
-order: 3
+order: 5
 ---
 
 For an additional layer of security, Accumulo can encrypt files stored on disk.  On Disk encryption was reworked 
diff --git a/_docs-2/security/overview.md b/_docs-2/security/overview.md
index f007e7bc..5fd9ce74 100644
--- a/_docs-2/security/overview.md
+++ b/_docs-2/security/overview.md
@@ -4,60 +4,34 @@ category: security
 order: 1
 ---
 
-This page provides an overview of Accumulo's security features.
+Accumulo has the following security features:
 
-A few Accumulo security features have on their own documentation page:
+* Only [authenticated][Authentication] users can access Accumulo.
+  * [Kerberos] can be enabled to replace Accumulo's default, password-based authentication
+* Users can only perform actions if they are given [permission][Permissions].
+* Users can only view [labeled data]({% durl security/authorizations#security-labels %}) that they are [authorized][Authorizations] to see.
+* Data can be encrypted [on disk]({% durl security/on-disk-encryption %}) and [over-the-wire]({% durl security/wire-encryption %})
 
-* [Security Labels]({% durl security/labels %})
-* [On Disk Encryption]({% durl security/on-disk-encryption %})
-* [Wire Encryption]({% durl security/wire-encryption %})
-* [Kerberos]({% durl security/kerberos %})
+## Implementation
 
-## Pluggable Security
+Below is a description of how security is implemented in Accumulo.
 
-Accumulo has a pluggable security mechanism. It can be broken into three actions: authentication, 
-authorization, and permission handling.
-
-Authentication verifies the identity of a user. In Accumulo, authentication occurs when
-the `usingToken'` method of the [AccumuloClient] builder is called with a principal (i.e username)
-and an [AuthenticationToken] which is an interface with multiple implementations. The most
-common implementation is [PasswordToken] which is the default authentication method for Accumulo
-out of the box.
-
-```java
-AccumuloClient client = Accumulo.newClient()
-                    .forInstance("myinstance", "zookeeper1,zookeper2")
-                    .usingToken("user", new PasswordToken("passwd")).build();
-```
-
-Once a user is authenticated by the Authenticator, the user has access to the other actions within
-Accumulo. All actions in Accumulo are ACLed, and this ACL check is handled by the Permission
-Handler. This is what manages all of the permissions, which are divided in system and per table
-level. From there, if a user is doing an action which requires authorizations, the Authorizor is
+Once a user is authenticated by the [Authenticator], the user has access to the other actions within
+Accumulo. All actions in Accumulo are ACLed, and this ACL check is handled by the [PermissionHandler].
+This is what manages all of the [permissions], which are divided in system and per table
+level. From there, if a user is doing an action which requires authorizations, the [Authorizor] is
 queried to determine what authorizations the user has.
 
 This setup allows a variety of different mechanisms to be used for handling different aspects of
-Accumulo's security. A system like Kerberos can be used for authentication, then a system like LDAP
+Accumulo's security. A system like [Kerberos] can be used for [authentication], then a system like LDAP
 could be used to determine if a user has a specific permission, and then it may default back to the
-default ZookeeperAuthorizor to determine what Authorizations a user is ultimately allowed to use.
+default [Authorizor] to determine what Authorizations a user is ultimately allowed to use.
 This is a pluggable system so custom components can be created depending on your need.
 
-## Secure Authorizations Handling
-
-For applications serving many users, it is not expected that an Accumulo user
-will be created for each application user. In this case an Accumulo user with
-all authorizations needed by any of the applications users must be created. To
-service queries, the application should create a scanner with the application
-user's authorizations. These authorizations could be obtained from a trusted 3rd
-party.
-
-Often production systems will integrate with Public-Key Infrastructure (PKI) and
-designate client code within the query layer to negotiate with PKI servers in order
-to authenticate users and retrieve their authorization tokens (credentials). This
-requires users to specify only the information necessary to authenticate themselves
-to the system. Once user identity is established, their credentials can be accessed by
-the client code and passed to Accumulo outside of the reach of the user.
-
-[AccumuloClient]: {% jurl org.apache.accumulo.core.client.AccumuloClient %}
-[AuthenticationToken]: {% jurl org.apache.accumulo.core.client.security.tokens.AuthenticationToken %}
-[PasswordToken]: {% jurl org.apache.accumulo.core.client.security.tokens.PasswordToken %}
+[Kerberos]: {% durl security/kerberos %}
+[authentication]: {% durl security/authentication %}
+[authorizations]: {% durl security/authorizations %}
+[permissions]: {% durl security/permissions %}
+[Authenticator]: {% jurl org.apache.accumulo.server.security.handler.Authenticator %}
+[Authorizor]: {% jurl org.apache.accumulo.server.security.handler.Authorizor %}
+[PermissionHandler]: {% jurl org.apache.accumulo.server.security.handler.PermissionHandler %}
diff --git a/_docs-2/security/permissions.md b/_docs-2/security/permissions.md
new file mode 100644
index 00000000..e2a9117b
--- /dev/null
+++ b/_docs-2/security/permissions.md
@@ -0,0 +1,72 @@
+---
+title: Permissions
+category: security
+order: 3
+---
+
+Accumulo users can only perform actions if they are given permission.
+
+Accumulo has three types of permissions:
+
+* [SystemPermission]
+* [NamespacePermission]
+* [TablePermission]
+
+These permissions are managed by [SecurityOperations] in Java API or the [Accumulo shell][shell].
+
+## Configuration
+
+Accumulo's [PermissionHandler] is configured by setting {% plink instance.security.permissionHandler %}.
+
+The default permission handler is described below.
+
+## Granting permission
+
+Users can be granted permissions in the shell:
+
+```
+root@uno> grant System.CREATE_TABLE -s -u bob
+```
+
+Or in the Java API using [SecurityOperations]:
+
+```java
+client.securityOperations().grantSystem("bob", SystemPermission.CREATE_TABLE);
+```
+
+## View permissions
+
+Permissions can be listed for a user in the shell:
+
+```
+root@uno> userpermissions -u bob
+System permissions: System.CREATE_TABLE, System.DROP_TABLE
+
+Namespace permissions (accumulo): Namespace.READ
+
+Table permissions (accumulo.metadata): Table.READ
+Table permissions (accumulo.replication): Table.READ
+Table permissions (accumulo.root): Table.READ
+```
+
+## Revoking permissions
+
+Permissions can be revoked for a user in the shell
+
+```
+root@uno> revoke System.CREATE_TABLE -s -u bob
+```
+
+Or in the Java API using [SecurityOperations]:
+
+```java
+client.securityOperations().revokeSystemPermission("bob", SystemPermission.CREATE_TABLE);
+```
+
+[shell]: {% durl getting-started/shell %}
+[PermissionHandler]: {% jurl org.apache.accumulo.server.security.handler.PermissionHandler %}
+[SystemPermission]: {% jurl org.apache.accumulo.core.security.SystemPermission %}
+[NamespacePermission]: {% jurl org.apache.accumulo.core.security.NamespacePermission %}
+[TablePermission]: {% jurl org.apache.accumulo.core.security.TablePermission %}
+[SecurityOperations]: {% jurl org.apache.accumulo.core.client.admin.SecurityOperations %}
+
diff --git a/_docs-2/security/wire-encryption.md b/_docs-2/security/wire-encryption.md
index 35ad64c2..27f5d515 100644
--- a/_docs-2/security/wire-encryption.md
+++ b/_docs-2/security/wire-encryption.md
@@ -1,7 +1,7 @@
 ---
 title: Wire Encryption
 category: security
-order: 4
+order: 6
 ---
 
 Accumulo, through Thrift's TSSLTransport, provides the ability to encrypt


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services