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


This chapter covers security configuration for {geode-name}, which includes both authentication and authorization
(collectively, auth) as well as Transport Layer Security (TLS) using SSL.

NOTE: Securing data at rest is not supported by {geode-name}.

TIP: See 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 and Authorization

{geode-name} employs username- and password-based {apache-geode-docs}/managing/security/authentication_overview.html[authentication]
and 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].

NOTE: SBDG will eventually provide support for and integration with
https://spring.io/projects/spring-security[Spring Security].

When you use Spring Boot for {geode-name}, which builds 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 one or more
Apache Shiro https://shiro.apache.org/realm.html[Realms] as beans in the Spring `ApplicationContext`.

Consider the following example:

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

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

    // ...
}
----
====

When an Apache Shiro Realm (such as `DefaultLdapRealm`) is declared and registered in the Spring `ApplicationContext`
as a Spring bean, Spring Boot automatically detects this `Realm` bean (or `Realm` beans if more than one is configured),
and the servers in the {geode-name} cluster are automatically configured with authentication and authorization enabled.

Alternatively, you can provide a 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 discovers your custom, application-specific `SecurityManager` implementation and configures 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 and authorization of your
servers over implementing {geode-name}'s `SecurityManager` interface.

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

When servers in an {geode-name} cluster have been configured with authentication and authorization enabled, clients
must authenticate when connecting.

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

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

To enable auth for clients that connect to a secure {geode-name} cluster, you need only set a username and password
in Spring Boot `application.properties`:

.Spring Boot `application.properties` for the client
====
[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} handles the rest.

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

Enabling auth for clients that connect to a {pivotal-cloudcache-name} service instance (PCC)
in {pivotal-cloudfoundry-name} (PCF) is even easier: You need do nothing.

If your Spring Boot application uses SBDG and is bound to PCC, when you deploy (that is, `cf push`) your application
to PCF, Spring Boot for {geode-name} extracts the required auth credentials from the environment that you set up when
you provisioned a PCC service instance in your PCF organization and space. PCC automatically assigns two users with
roles of `cluster_operator` and `developer`, respectively, to any Spring Boot application bound to the PCC service
instance.

By default, SBDG auto-configures your Spring Boot application to run with the user that has the `cluster_operator` role.
This ensures that your Spring Boot application has the necessary permission (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 <<cloudfoundry-cloudcache-security-auth-runtime-user-configuration,Running Spring Boot applications as a specific user>> section
in the <<cloudfoundry,Pivotal CloudFoundry>> 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 you use PCC and PCF.

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

Securing data in motion is also essential to the integrity of your Spring [Boot] applications.

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

Therefore, {geode-name} supports SSL between clients and servers, between JMX clients (such as Gfsh) and the Manager,
between HTTP clients when you use the Developer REST API or Pulse, between peers in the cluster, and when you use
the WAN Gateway to connect multiple sites (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. These properties translate to the appropriate
`javax.net.ssl.*` properties required by the JRE to create secure socket connections by using
https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html[JSSE].

However, 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.

You can create a `trusted.keystore` as a JKS-based `KeyStore` file and place it in one of three well-known locations:

* In your application JAR file at the root of the classpath.
* In your Spring Boot application's working directory.
* 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 one of these three well-known locations, Spring Boot
for {geode-name} automatically configures your client to use SSL socket connections.

If you use 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 also applies the same procedure to enable SSL on the servers (between peers).

TIP: During development, it is convenient to *not* 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 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 one of the default, well-known locations searched by Spring Boot:

.Accessing a secure `trusted.keystore` by location
====
[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 nor Spring Data for {geode-name} offer any support for securing your
data while at rest (for example, 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 third-party solutions, such as
disk encryption, which is usually highly contextual and technology-specific.

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