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
Below are the list of operations with their corresponding GeodePermission:
Client-Server Operations
Client Operations | Required GeodePermission |
---|---|
get function attribute | CLUSTER:READ |
create region | DATA:MANAGE |
destroy region | DATA:MANAGE |
get keyset | DATA:READ:regionName |
query | DATA:READ:regionName |
region.getAll | DATA:READ:regionName |
region.getEntry | DATA:READ:regionName |
getAll (list of keys) | DATA:READ:regionName:key |
region.containsKeyOnServer(key) | DATA:READ:regionName:key |
region.get(key) | DATA:READ:regionName:key |
registerInterest | DATA:READ:regionName:key if key is specified, otherwise DATA:READ:regionName |
unregister interest | DATA:READ:regionName:key if key is specified, otherwise DATA:READ:regionName |
execute function | DATA:WRITE |
clear region | DATA:WRITE:regionName |
putAll | DATA:WRITE:regionName |
region.clear | DATA:WRITE:regionName |
region.removeAll | DATA:WRITE:regionName |
destroy key | DATA:WRITE:regionName:key |
invalidate key | DATA:WRITE: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.replace | DATA:WRITE:regionName:key |
GFSH Commands
Commands | Required GeodePermission |
---|---|
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 |
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 |
change loglevel --loglevel=severe --member=server1 | CLUSTER:WRITE |
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 if regionName is specified, otherwise DATA:MANAGE |
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 |
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 |
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 |
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 |
remove --region=region1 | DATA:WRITE:regionName, if key is specified, then DATA:WRITE:regionName:key |
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.
JMX Operations
Bean Operations | Permission |
---|---|
DistributedSystemMXBean.shutdownAllMembers | CLUSTER:MANAGE |
ManagerMXBean.start | CLUSTER:MANAGE |
ManagerMXBean.stop | CLUSTER:MANAGE |
MemberMXBean.createManager()) | CLUSTER:MANAGE |
MemberMXBean.shutDownMember | CLUSTER:MANAGE |
Mbeans get attributes | CLUSTER:READ |
MemberMXBean.showLog | CLUSTER:READ |
DistributedSystemMXBean.changeAlertLevel | CLUSTER:WRITE |
ManagerMXBean.setPulseURL | CLUSTER:WRITE |
ManagerMXBean.setStatusMessage | CLUSTER:WRITE |
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 |
CacheServerMXBean.executeContinuousQuery("bar")) | DATA:READ |
DistributedSystemMXBean.backupAllMembers | DATA:READ |
DistributedSystemMXBean.queryData | DATA:READ |
DistributedSystemMXBean.queryDataForCompressedResult | DATA:READ |