Geode is introducing a security features which allow you to control authentication/authorization on all aspects of Geode in one implementation. When Integrated Security is turned on, all client/server communications, peer to peer, gateway authentication, jmx operations, gfsh commands and Pulse are all protected with this security mechanism.
1. No changes for existing implementations of Authentication/Authorization for client-server security
The API for Authenticator and AccessControl has not changed. Your implementations of those are still honored in client/server communication if you choose not to implement the new security interface. However, these two are deprecated now and will be removed in the future.
2. Introduction of security-manager configuration and SecurityManager interface for Integrated Security
To turn on integrated security, your will need to start your server/locator with this line in your gemfire.properties file:
security-manager = com.abc.security.MySecurityManager
It is the class name that implements the SecurityManager interface. Make sure your class has a zero argument constructor so that we can instantiate the object. SecurityManger is the new interface you will need to implement for both authentication and authorization. See SecurityManger javadoc for details. You can use SampleSecurityManager as an example to write your own implementation.
3. Introduction of GeodePermission
In SecurityManager, you will see a GeodePermission is passed in the authorization call. GeodePermission is an object that defines the nature of the operation the Principal is trying to perform.
GeodePermission is in one of those forms:
Resource:Operation Resource:Operation:RegionName Resource:Operation:RegionName:Key
All Resources are enumerated via the enum GeodePermission.Resource, which are "CLUSTER" and "DATA".
All Operations are enumerated via the enum GeodePermission.Operation, which are "MANAGE", "READ" and "WRITE". Note "MANAGE" does not imply "WRITE", nor "WRITE" implies "READ" either.
RegionName and Key are provided for region key access as well.
For example, you can see a GeodePermission defined as "CLUSTER:READ", "CLUSTER:MANAGE", "DATDA:READ", "DATA:READ:regionA", or "DATA:READ:regionA:key1".
Note GeodePermission is hierarchical. If you have permission for "DATA:READ", you automatically have data read permission on all regions and all keys, i.e. you have permission for "DATA:READ:regionA". If you have permission for "DATA:READ:regionA", you automatically have data read permission on all keys in regionA, i.e, you have permission for "DATA:READ:regionA:key1".
4. Introduction of PostProcessor
We completely redo the way we call post processing. Now the interface is a lot simpler. Before the value is sent to the you, it gets a pass through the post processor if there is any. You specify your post processor with this line in your gemfire.properties file:
security-post-processor = com.abc.security.MyPostProcessor
It is the class name that implements the PostProcessor interface. Make sure your class has a zero argument constructor so that we can instantiate the object. See PostProcessor javadoc for details. You can use SamplePostProcessor as an example to write your own implementation.
5. Operations and their corresponding GeodePermission
Client-Server
Client Operations | Required GeodePermission |
---|---|
region.containsKeyOnServer(key) | DATA:READ:regionName:key |
region.destroy(key) | DATA:WRITE:regionName:key |
region.invalidate(key) | DATA:WRITE:regionName:key |
region.put(key, value) | DATA:WRITE:regionName:key |
region.get(key) | DATA:READ:regionName:key |
region.replace | |
region.putIfAbsent | |
createRegion | DATA:MANAGE |
destroyRegion | DATA:MANAGE |
executeFunction | DATA:WRITE |
executeRegionFunction | DATA:WRITE |
region.getAll | DATA:READ:regionName |
region.getEntry | DATA:READ:regionName |
region.clear | DATA:WRITE:regionName |
region.registerInterest | DATA:READ:regionName:key |
region.registerInterestRegex | DATA:READ:regionName |
region.registerInterestList | DATA:READ:regionName |
region.removeAll | DATA:WRITE:regionName |
region.unRegisterInterest | DATA:READ:regionName:key |
region.unRegisterInterestRegex | DATA:READ:regionName |
region.unRegisterInterestList | DATA:READ:regionName |
query | DATA:READ:regionName |
Pulse
Pulse access is divided into two main categories, namely access to the Data Browser page and everything else.
The Data Browser page requires the permissions CLUSTER:READ and DATA:READ. Access to all other pages requires only CLUSTER:READ permission.
GFSH and JMX
Following are lists for gfsh commands, (highlighted in green), and JMX operations with their corresponding permissions. Permissions appear as Resource:OperationCode
tuples.
Entries with a green background are gfsh commands; the others are JMX operations.
Cluster MANAGEment Operations | Permission |
---|---|
alter runtime | CLUSTER:MANAGE |
gc | CLUSTER:MANAGE |
shutdown | CLUSTER:MANAGE |
startManager | CLUSTER:MANAGE |
stop locator --name=locator1 | CLUSTER:MANAGE |
stop server --name=server1 | CLUSTER:MANAGE |
DistributedSystemMXBean.shutdownAllMembers | CLUSTER:MANAGE |
ManagerMXBean.start | CLUSTER:MANAGE |
ManagerMXBean.stop | CLUSTER:MANAGE |
MemberMXBean.createManager()) | CLUSTER:MANAGE |
MemberMXBean.shutDownMember | CLUSTER:MANAGE |
Cluster READ Operations | Permission |
---|---|
countDurableCqEvents | CLUSTER:READ |
describe client --clientID=172.16.196.144 | CLUSTER:READ |
describe config --member=Member1 | CLUSTER:READ |
describe disk-store --name=foo --member=baz | CLUSTER:READ |
describe member --name=server1 | CLUSTER:READ |
describe offline-disk-store --name=foo --disk-dirs=bar | CLUSTER:READ |
describe region --name=value | CLUSTER:READ |
export cluster-configuration --zip-file-name=mySharedConfig.zip | CLUSTER:READ |
export config --member=member1 | CLUSTER:READ |
export logs --dir=data/logs | CLUSTER:READ |
export stack-traces --file=stack.txt | CLUSTER:READ |
exportLogs | CLUSTER:READ |
exportStackTrace | CLUSTER:READ |
list async-event-queues | CLUSTER:READ |
list clients | CLUSTER:READ |
list deployed | CLUSTER:READ |
list disk-stores | CLUSTER:READ |
list durable-cqs --durable-client-id=client1 | CLUSTER:READ |
list functions | CLUSTER:READ |
list gateways | CLUSTER:READ |
list indexes | CLUSTER:READ |
list members | CLUSTER:READ |
list regions | CLUSTER:READ |
netstat --member=server1 | CLUSTER:READ |
show dead-locks --file=deadlocks.txt | CLUSTER:READ |
show log --member=locator1 --lines=5 | CLUSTER:READ |
show metrics | CLUSTER:READ |
show missing-disk-stores | CLUSTER:READ |
show subscription-queue-size --durable-client-id=client1 | CLUSTER:READ |
showLog | CLUSTER:READ |
status cluster-config-service | CLUSTER:READ |
status gateway-receiver | CLUSTER:READ |
status gateway-sender | CLUSTER:READ |
Mbeans get attributes | CLUSTER:READ |
MemberMXBean.showLog | CLUSTER:READ |
Cluster WRITE Operations | Permission |
---|---|
change loglevel --loglevel=severe --member=server1 | CLUSTER:WRITE |
DistributedSystemMXBean.changeAlertLevel | CLUSTER:WRITE |
ManagerMXBean.setPulseURL | CLUSTER:WRITE |
ManagerMXBean.setStatusMessage | CLUSTER:WRITE |
Data MANAGE Operations | Permission |
---|---|
alter disk-store --name=foo --region=xyz --disk-dirs=bar | DATA:MANAGE |
alter region --name=region1 --eviction-max=5000 | DATA:MANAGE:REGIONNAME |
clear defined indexes | DATA:MANAGE |
close durable-client --durable-client-id=client1 | DATA:MANAGE |
close durable-cq --durable-client-id=client1 --durable-cq-name=cq1 | DATA:MANAGE |
compact disk-store --name=foo | DATA:MANAGE |
compact offline-disk-store --name=foo --disk-dirs=bar | DATA:MANAGE |
configure pdx --read-serialized=true | DATA:MANAGE |
create async-event-queue --id=myAEQ --listener=myApp.myListener | DATA:MANAGE |
create defined indexes | DATA:MANAGE |
create disk-store --name=foo --dir=bar | DATA:MANAGE |
create gateway-receiver | DATA:MANAGE |
create gateway-sender --id=sender1 --remote-distributed-system-id=2 | DATA:MANAGE |
create index --name=myKeyIndex --expression=region1.Id --region=region1 --type=key | DATA:MANAGE:REGIONNAME |
create region --name=region12 | DATA:MANAGE |
define index --name=myIndex1 --expression=exp1 --region=/exampleRegion | DATA:MANAGE:REGIONNAME |
deploy --jar=group1_functions.jar --group=Group1 | DATA:MANAGE |
destroy disk-store --name=foo | DATA:MANAGE |
destroy function --id=InterestCalculations | DATA:MANAGE |
destroy index --member=server2 | DATA:MANAGE:REGIONNAME |
destroy region --name=value | DATA:MANAGE |
import cluster-configuration --zip-file-name=value | DATA:MANAGE |
load-balance gateway-sender --id=sender1 | DATA:MANAGE |
pause gateway-sender --id=sender1 | DATA:MANAGE |
pdx rename --old=com.gemstone --new=com.pivotal --disk-store=ds1 --disk-dirs=/diskDir1 | DATA:MANAGE |
rebalance --include-region=region1 | DATA:MANAGE |
remove --region=region1 | DATA:MANAGE, if key is specified...... |
resume gateway-sender --id=sender1 | DATA:MANAGE |
revoke missing-disk-store --id=foo | DATA:MANAGE |
start gateway-receiver | DATA:MANAGE |
start gateway-sender --id=sender1 | DATA:MANAGE |
stop gateway-receiver | DATA:MANAGE |
stop gateway-sender --id=sender1 | DATA:MANAGE |
undeploy --group=Group1 | DATA:MANAGE |
CacheServerMXBean.closeAllContinuousQuery | DATA:MANAGE |
CacheServerMXBean.closeContinuousQuery | DATA:MANAGE |
CacheServerMXBean.removeIndex("foo")) | DATA:MANAGE |
CacheServerMXBean.stopContinuousQuery("bar")) | DATA:MANAGE |
DiskStoreMXBean.flush()) | DATA:MANAGE |
DiskStoreMXBean.forceCompaction()) | DATA:MANAGE |
DiskStoreMXBean.forceRoll()) | DATA:MANAGE |
DiskStoreMXBean.setDiskUsageCriticalPercentage(0 | DATA:MANAGE |
DiskStoreMXBean.setDiskUsageWarningPercentage(0 | DATA:MANAGE |
DistributedSystemMXBean.revokeMissingDiskStores | DATA:MANAGE |
DistributedSystemMXBean.setQueryCollectionsDepth | DATA:MANAGE |
DistributedSystemMXBean.setQueryResultSetLimit | DATA:MANAGE |
GatewayReceiverMXBean.pause()) | DATA:MANAGE |
GatewayReceiverMXBean.rebalance()) | DATA:MANAGE |
GatewayReceiverMXBean.resume()) | DATA:MANAGE |
GatewayReceiverMXBean.start | DATA:MANAGE |
GatewayReceiverMXBean.stop | DATA:MANAGE |
GatewaySenderMXBean.pause | DATA:MANAGE |
GatewaySenderMXBean.rebalance | DATA:MANAGE |
GatewaySenderMXBean.resume | DATA:MANAGE |
GatewaySenderMXBean.start | DATA:MANAGE |
GatewaySenderMXBean.stop | DATA:MANAGE |
LockServiceMBean.becomeLockGrantor()) | DATA:MANAGE |
MemberMXBean.compactAllDiskStores | DATA:MANAGE |
Data READ Operations | Permission |
---|---|
backup disk-store --dir=foo | DATA:READ |
export data --region=region1 --file=foo.txt --member=value | DATA:READ:REGIONNAME |
get --key=key1 --region=region1 | DATA:READ:regionName:key |
locateEntry | DATA:READ:regionName:key |
query --query='SELECT * FROM /region1' | DATA:READ:REGIONNAME |
CacheServerMXBean.executeContinuousQuery("bar")) | DATA:READ |
DistributedSystemMXBean.backupAllMembers | DATA:READ |
DistributedSystemMXBean.queryData | DATA:READ |
DistributedSystemMXBean.queryDataForCompressedResult | DATA:READ |
Data WRITE Operations | Permission |
---|---|
execute function --id=InterestCalculations --group=Group1 | DATA:WRITE |
import data --region=region1 --file=foo.txt --member=value | DATA:WRITE:REGIONNAME |
put --key=key1 --value=value1 --region=region1 | DATA:WRITE:REGIONNAME:key |