Geode is introducing a security implementation which allows you to control the authentication/authorization of all Geode entities within 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 single 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 servers/locators with this property set in your gemfire.properties
file:
security-manager = com.example.security.MySecurityManager
This property identifies the class name of the SecurityManager
interface implementation. SecurityManager
is the new interface you will need to implement for both authentication and authorization. Make sure your class has a zero argument constructor so that we can instantiate the object. See the SecurityManager
javadoc for details. There is a SampleSecurityManager
in the geode-core/src/main/java/org/apache/geode/security/templates
directory that you can use as an example to write your own implementation.
3. Introduction of ResourcePermission
In SecurityManager
, you will see that a ResourcePermission
is passed in the authorization call. ResourcePermission
is an object that defines the nature of the operation the Principal is trying to perform.
ResourcePermission
is in one of those forms:
Resource:Operation Resource:Operation:RegionName Resource:Operation:RegionName:Key
All Resources are enumerated via the enum ResourcePermission.Resource
, currently CLUSTER
and DATA.
All Operations are enumerated via the enum ResourcePermission.Operation
, which are MANAGE
, READ
, and WRITE
. Note that MANAGE
does not imply WRITE
, and WRITE
does not imply READ
.
RegionName
and Key
are provided for those operations that are to be authorized based upon a region key access as well. For example, you can see a ResourcePermission
defined as CLUSTER:READ
, CLUSTER:MANAGE
, DATA:READ
, DATA:READ:regionA
, or DATA:READ:regionA:key1
.
Note that a ResourcePermission
is hierarchical. If a principal has permission for DATA:READ
, it automatically has data read permission on all regions and all keys. That is, it has permission for DATA:READ:regionA
. Given permission for DATA:READ:regionA
, the principal automatically has data read permission on all keys in regionA. That is, it has 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 | DATA: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 |
show log | 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 |