[[geode-security]]
== Security
:geode-name: {apache-geode-name}


This sections covers Security configuration for {geode-name}, which includes both Authentication & Authorization
(collectively, Auth) as well as Transport Layer Security (TLS) using SSL.

NOTE: Securing Data at Rest is not supported by {geode-name}.

TIP: Refer to the corresponding Sample link:guides/boot-security.html[Guide] and {github-samples-url}/boot/security[Code]
to see Spring Boot Security for {geode-name} in action!

[[geode-security-auth]]
=== Authentication & Authorization

{geode-name} employs Username and Password based {apache-geode-docs}/managing/security/authentication_overview.html[Authentication]
along with Role-based {apache-geode-docs}/managing/security/authorization_overview.html[Authorization] to secure
your client to server data exchanges and operations.

Spring Data for {geode-name} provides {spring-data-geode-docs-html}/#bootstrap-annotation-config-security[first-class support]
for {geode-name}'s Security framework, which is based on the
{apache-geode-javadoc}/org/apache/geode/security/SecurityManager.html[SecurityManager] interface.
Additionally, {geode-name}'s Security framework is integrated with https://shiro.apache.org/[Apache Shiro],
making the security for servers an even easier and more familiar task.

NOTE: Eventually, support and integration with https://spring.io/projects/spring-security[Spring Security]
will be provided by SBDG as well.

When you use Spring Boot for {geode-name}, which builds on the bits provided in Spring Data for {geode-name},
it makes short work of enabling Auth in both your clients and servers.

[[geode-security-auth-servers]]
==== Auth for Servers

The easiest and most standard way to enable Auth in the servers of your cluster is to simply define 1 or more
Apache Shiro https://shiro.apache.org/realm.html[Realms] as beans in the Spring `ApplicationContext`.

For example:

.Declaring an Apache Shiro Realm
[source,java]
----
@Configuration
class ApacheGeodeSecurityConfiguration {

    @Bean
    DefaultLdapRealm ldapRealm() {
        return new DefaultLdapRealm();
    }

    // ...
}
----

When an Apache Shiro Realm (e.g. `DefaultLdapRealm`) is declared and registered in the Spring `ApplicationContext` as a
Spring bean, Spring Boot will automatically detect this `Realm` bean (or `Realm` beans if more than 1 is configured)
and the {geode-name} servers in the cluster will automatically be configured with Authentication and Authorization
enabled.

Alternatively, you can provide an custom, application-specific implementation of {geode-name}'s
{apache-geode-javadoc}/org/apache/geode/security/SecurityManager.html[SecurityManager] interface,
declared and registered as a bean in the Spring `ApplicationContext`:

.Declaring a custom {geode-name} `SecurityManager`
[source,java]
----
@Configuration
class ApacheGeodeSecurityConfiguration {

    @Bean
    CustomSecurityManager customSecurityManager() {
        return new CustomSecurityManager();
    }

    // ...
}
----

Spring Boot will discover your custom, application-specific `SecurityManager` implementation and configure
the servers in the {geode-name} cluster with Authentication and Authorization enabled.

TIP: The Spring team recommends that you use Apache Shiro to manage the Authentication & Authorization of your
{geode-name} servers over implementing {geode-name}'s `SecurityManager` interface.

[[geode-security-auth-clients]]
==== Auth for Clients

When {geode-name} servers have been configured with Authentication & Authorization enabled, then clients must
authenticate when connecting.

Spring Boot for {geode-name} makes this easy, regardless of whether you are running your Spring Boot, `ClientCache`
applications in a local, non-managed environment or even when running in a cloud managed environment.

[[geode-security-auth-clients-non-managed]]
===== Non-Managed Auth for Clients

To enable Auth for clients connecting to a secure {geode-name} cluster, you simply only need to set a username
and password in your Spring Boot `application.properties` file:

[source,txt]
----
# Spring Boot client application.properties

spring.data.gemfire.security.username = jdoe
spring.data.gemfire.security.password = p@55w0rd
----

Spring Boot for {geode-name} will handle the rest.

[[geode-secuirty-auth-clients-managed]]
===== Managed Auth for Clients

Enabling Auth for clients connecting to a Pivotal Cloud Cache (PCC) service instance in Pivotal CloudFoundry (PCF)
is even easier.

You do not need to do anything!

When your Spring Boot application uses SBDG and is bound to PCC, then when you push (i.e. deploy) your app to PCF,
Spring Boot for {geode-name} will extract the required Auth credentials from the environment that you setup when you
provisioned a PCC service instance in your PCF organization & space.  PCC automatically assigns 2 users with roles
"_cluster_operator_" and "_developer_", respectively, to any Spring Boot application bound to the PCC service instance.

By default, SBDG will auto-configure your Spring Boot app to run with the user having the "_cluster_operator" Role.
This ensures that your Spring Boot app has the necessary permissions (i.e. Authorization) to perform all data access
operations on the servers in the PCC cluster including, for example, pushing configuration metadata from the client
to the servers in the PCC cluster.

See the section, <<[cloudfoundry-cloudcache-security-auth-runtime-user-configuration,Running Spring Boot applications as a specific user>>,
in the <<cloudfoundry,Pivotal Cloud Foundry>> chapter for additional details on user authentication and authorization.

See the <<cloudfoundry,chapter>> titled '_Pivotal CloudFoundry_' for more general details.

See the {pivotal-cloudcache-docs}/security.html[Pivotal Cloud Cache documentation] for security details
when using PCC and PCF.

[[geode-security-ssl]]
=== Transport Layer Security using SSL

Securing data in motion is also essential to the integrity of your application.

For instance, it would not do much good to send usernames and passwords over plain text Socket connections
between your clients and servers, nor send sensitive data over those same connections.

Therefore, {geode-name} supports SSL between clients & servers, JMX clients (e.g. _Gfsh_) and the _Manager_,
HTTP clients when using the Developer REST API or _Pulse_, between peers in the cluster, and when using the WAN Gateway
to connect multiple sites (i.e. clusters).

Spring Data for {geode-name} provides
https://docs.spring.io/spring-data/geode/docs/current/reference/html/#bootstrap-annotation-config-ssl[first-class support]
for configuring and enabling SSL as well.  Still, Spring Boot makes it even easier to configure and enable SSL,
especially during development.

{geode-name} requires certain properties to be configured, which translate to the appropriate
`javax.net.ssl.*` properties required by the JRE, to create Secure Socket Connections using
https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html[JSSE].

But, ensuring that you have set all the required SSL properties correctly is an error prone and tedious task.
Therefore, Spring Boot for {geode-name} applies some basic conventions for you, out-of-the-box.

Simply create a `trusted.keystore`, JKS-based `KeyStore` file and place it in 1 of 3 well-known locations:

1. In your application JAR file at the root of the classpath.
2. In your Spring Boot application's working directory.
3. In your user home directory (as defined by the `user.home` Java System property).

When this file is named `trusted.keystore` and is placed in 1 of these 3 well-known locations, Spring Boot
for {geode-name} will automatically configure your client to use SSL Socket connections.

If you are using Spring Boot to configure and bootstrap an {geode-name} server:

.Spring Boot configured and bootstrapped {geode-name} server
[source,java]
----
@SpringBootApplication
@CacheServerApplication
class SpringBootApacheGeodeCacheServerApplication {
    // ...
}
----

Then, Spring Boot will apply the same procedure to enable SSL on the servers, between peers, as well.

TIP: During development it is convenient *not* to set a `trusted.keystore` password when accessing the keys in the JKS
file. However, it is highly recommended that you secure the `trusted.keystore` file when deploying your application to
a production environment.

If your `trusted.keystore` file is secured with a password, you will need to additionally specify the following property:

.Accessing a secure `trusted.keystore`
[source,txt]
----
# Spring Boot application.properties

spring.data.gemfire.security.ssl.keystore.password = p@55w0rd!
----

You can also configure the location of the keystore and truststore files, if they are separate, and have not been placed
in 1 of the default, well-known locations searched by Spring Boot:

.Accessing a secure `trusted.keystore`
[source,txt]
----
# Spring Boot application.properties

spring.data.gemfire.security.ssl.keystore = /absolute/file/system/path/to/keystore.jks
spring.data.gemfire.security.ssl.keystore.password = keystorePassword
spring.data.gemfire.security.ssl.truststore = /absolute/file/system/path/to/truststore.jks
spring.data.gemfire.security.ssl.truststore.password = truststorePassword
----

See the SDG {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html[EnableSsl]
annotation for all the configuration attributes and the corresponding properties expressed in `application.properties`.

[[geode-security-encryption]]
=== Securing Data at Rest

Currently, neither {geode-name} nor Spring Boot or Spring Data for {geode-name} offer any support for securing your data
while at rest (e.g. when your data has been overflowed or persisted to disk).

To secure data at rest when using {geode-name}, with or without Spring, you must employ 3rd party solutions like disk
encryption, which is usually highly contextual and technology specific.

For example, to secure data at rest using Amazon EC2, see
https://aws.amazon.com/blogs/security/how-to-protect-data-at-rest-with-amazon-ec2-instance-store-encryption/[Instance Store Encryption].
