0
# Security and ACL Management
1
2
Access control and authentication mechanisms for securing Zookeeper nodes. Includes ACL creation, permission management, and authentication schemes with support for digest, IP, SASL, and world authentication patterns.
3
4
## Capabilities
5
6
### Access Control Lists (ACLs)
7
8
ACL data structures and permission management for controlling node access with fine-grained permission control and multiple authentication schemes.
9
10
```python { .api }
11
class ACL:
12
def __init__(self, perms, id):
13
"""
14
Access Control List entry.
15
16
Parameters:
17
- perms (int): Permission mask (combination of Permissions constants)
18
- id (Id): Identity object specifying scheme and credential
19
20
Attributes:
21
- perms (int): Permission bitmask
22
- id (Id): Identity specification
23
"""
24
25
class Id:
26
def __init__(self, scheme, id):
27
"""
28
Identity specification for ACL.
29
30
Parameters:
31
- scheme (str): Authentication scheme (world, auth, digest, ip, sasl)
32
- id (str): Identity credential for the scheme
33
34
Attributes:
35
- scheme (str): Authentication scheme
36
- id (str): Identity credential
37
"""
38
39
class Permissions:
40
"""Permission constants for ACL entries."""
41
READ: int = 1 # Read node data and list children
42
WRITE: int = 2 # Write node data
43
CREATE: int = 4 # Create child nodes
44
DELETE: int = 8 # Delete node or child nodes
45
ADMIN: int = 16 # Set ACL permissions
46
ALL: int = 31 # All permissions (READ | WRITE | CREATE | DELETE | ADMIN)
47
```
48
49
### Pre-defined ACL Constants
50
51
Common ACL configurations for typical security patterns with appropriate permission sets for different use cases.
52
53
```python { .api }
54
# Identity constants
55
ANYONE_ID_UNSAFE = Id("world", "anyone")
56
"""Identity for world/anyone access (insecure)."""
57
58
AUTH_IDS = Id("auth", "")
59
"""Identity for authenticated users."""
60
61
# Pre-defined ACL lists
62
OPEN_ACL_UNSAFE = [ACL(Permissions.ALL, ANYONE_ID_UNSAFE)]
63
"""ACL allowing all permissions to anyone (insecure)."""
64
65
CREATOR_ALL_ACL = [ACL(Permissions.ALL, AUTH_IDS)]
66
"""ACL giving all permissions to creator only."""
67
68
READ_ACL_UNSAFE = [ACL(Permissions.READ, ANYONE_ID_UNSAFE)]
69
"""ACL allowing read permission to anyone (insecure)."""
70
```
71
72
### ACL Creation Functions
73
74
Utility functions for creating ACLs with specific permission sets and authentication schemes for common security patterns.
75
76
```python { .api }
77
def make_acl(scheme, credential, read=False, write=False, create=False,
78
delete=False, admin=False, all=False):
79
"""
80
Create an ACL with specified permissions.
81
82
Parameters:
83
- scheme (str): Authentication scheme (world, auth, digest, ip, sasl)
84
- credential (str): Authentication credential
85
- read (bool): Grant read permission
86
- write (bool): Grant write permission
87
- create (bool): Grant create permission
88
- delete (bool): Grant delete permission
89
- admin (bool): Grant admin permission
90
- all (bool): Grant all permissions
91
92
Returns:
93
list: List containing single ACL object
94
"""
95
96
def make_digest_acl(username, password, read=False, write=False, create=False,
97
delete=False, admin=False, all=False):
98
"""
99
Create a digest-based ACL.
100
101
Parameters:
102
- username (str): Username for digest authentication
103
- password (str): Password for digest authentication
104
- read (bool): Grant read permission
105
- write (bool): Grant write permission
106
- create (bool): Grant create permission
107
- delete (bool): Grant delete permission
108
- admin (bool): Grant admin permission
109
- all (bool): Grant all permissions
110
111
Returns:
112
list: List containing digest ACL
113
"""
114
115
def make_digest_acl_credential(username, password):
116
"""
117
Create digest credential string.
118
119
Parameters:
120
- username (str): Username for authentication
121
- password (str): Password for authentication
122
123
Returns:
124
str: Digest credential in format "username:base64(sha1(username:password))"
125
"""
126
```
127
128
### Authentication Schemes
129
130
Different authentication mechanisms supported by Zookeeper with appropriate credential formats and usage patterns.
131
132
```python { .api }
133
# Authentication scheme constants and patterns
134
135
# World scheme - open access (not recommended for production)
136
world_acl = [ACL(Permissions.ALL, Id("world", "anyone"))]
137
138
# Auth scheme - authenticated users only
139
auth_acl = [ACL(Permissions.ALL, Id("auth", ""))]
140
141
# Digest scheme - username/password authentication
142
digest_credential = make_digest_acl_credential("admin", "secret")
143
digest_acl = [ACL(Permissions.ALL, Id("digest", digest_credential))]
144
145
# IP scheme - IP address-based access control
146
ip_acl = [ACL(Permissions.READ, Id("ip", "192.168.1.0/24"))]
147
148
# SASL scheme - SASL authentication (Kerberos, etc.)
149
sasl_acl = [ACL(Permissions.ALL, Id("sasl", "principal@REALM"))]
150
```
151
152
### Client Authentication
153
154
Methods for authenticating clients with Zookeeper using various authentication schemes and credential management.
155
156
```python { .api }
157
# KazooClient authentication methods (from core-client.md)
158
def add_auth(self, scheme, credential):
159
"""
160
Add authentication credentials to client.
161
162
Parameters:
163
- scheme (str): Authentication scheme (digest, sasl, etc.)
164
- credential (str): Authentication credential
165
166
Raises:
167
- AuthFailedError: If authentication fails
168
"""
169
170
def add_auth_async(self, scheme, credential):
171
"""
172
Asynchronous authentication.
173
174
Returns:
175
IAsyncResult: Async result object
176
"""
177
```
178
179
### Node ACL Operations
180
181
Methods for getting and setting ACLs on Zookeeper nodes with version control and permission validation.
182
183
```python { .api }
184
# KazooClient ACL methods (from core-client.md)
185
def get_acls(self, path):
186
"""
187
Get ACLs for a node.
188
189
Parameters:
190
- path (str): Node path
191
192
Returns:
193
tuple: (acl_list, ZnodeStat) containing ACLs and node metadata
194
195
Raises:
196
- NoNodeError: If node doesn't exist
197
"""
198
199
def set_acls(self, path, acls, version=-1):
200
"""
201
Set ACLs for a node.
202
203
Parameters:
204
- path (str): Node path
205
- acls (list): List of ACL objects
206
- version (int): Expected ACL version (-1 for any version)
207
208
Returns:
209
ZnodeStat: Updated node metadata
210
211
Raises:
212
- NoNodeError: If node doesn't exist
213
- BadVersionError: If ACL version doesn't match
214
- InvalidACLError: If ACL format is invalid
215
"""
216
```
217
218
### SSL/TLS Configuration
219
220
Secure socket layer configuration for encrypted client-server communication with certificate management and validation.
221
222
```python { .api }
223
# KazooClient SSL parameters (from core-client.md)
224
def __init__(self, hosts="127.0.0.1:2181", ...,
225
keyfile=None, keyfile_password=None, certfile=None,
226
ca=None, use_ssl=False, verify_certs=True):
227
"""
228
SSL/TLS configuration parameters:
229
230
- keyfile (str): Path to SSL private key file
231
- keyfile_password (str): Password for encrypted private key
232
- certfile (str): Path to SSL certificate file
233
- ca (str): Path to SSL CA certificate file
234
- use_ssl (bool): Enable SSL/TLS connections
235
- verify_certs (bool): Verify SSL certificates
236
"""
237
```
238
239
### SASL Authentication
240
241
SASL (Simple Authentication and Security Layer) configuration for enterprise authentication integration with Kerberos and other mechanisms.
242
243
```python { .api }
244
# KazooClient SASL parameters (from core-client.md)
245
def __init__(self, hosts="127.0.0.1:2181", ...,
246
sasl_options=None, auth_data=None):
247
"""
248
SASL configuration parameters:
249
250
- sasl_options (dict): SASL mechanism options
251
- auth_data (list): List of (scheme, credential) tuples
252
"""
253
254
# SASL configuration example
255
sasl_options = {
256
'mechanism': 'GSSAPI',
257
'principal': 'zkclient/hostname@REALM'
258
}
259
```
260
261
## Usage Examples
262
263
### Basic ACL Usage
264
265
```python
266
from kazoo.client import KazooClient
267
from kazoo.security import make_digest_acl, make_acl, Permissions
268
from kazoo.security import OPEN_ACL_UNSAFE, CREATOR_ALL_ACL
269
270
zk = KazooClient()
271
zk.start()
272
273
try:
274
# Create node with open ACL (not recommended for production)
275
zk.create("/public", b"public data", acl=OPEN_ACL_UNSAFE)
276
277
# Create node with restricted access
278
admin_acl = make_digest_acl("admin", "secret", all=True)
279
zk.create("/private", b"private data", acl=admin_acl, makepath=True)
280
281
# Create node with mixed permissions
282
mixed_acl = [
283
make_acl("digest", "admin:hash", all=True)[0], # Admin full access
284
make_acl("digest", "user:hash", read=True, write=True)[0], # User read/write
285
make_acl("ip", "192.168.1.0/24", read=True)[0] # Network read-only
286
]
287
zk.create("/mixed", b"mixed access", acl=mixed_acl)
288
289
finally:
290
zk.stop()
291
```
292
293
### Authentication Example
294
295
```python
296
from kazoo.client import KazooClient
297
from kazoo.security import make_digest_acl_credential, make_digest_acl
298
from kazoo.exceptions import AuthFailedError
299
300
# Create client and authenticate
301
zk = KazooClient()
302
zk.start()
303
304
try:
305
# Add digest authentication
306
zk.add_auth("digest", "admin:secret")
307
308
# Create ACL for authenticated user
309
admin_acl = make_digest_acl("admin", "secret", all=True)
310
311
# Create protected node
312
zk.create("/secure/config", b'{"setting": "value"}',
313
acl=admin_acl, makepath=True)
314
315
# Access protected node (works because we're authenticated)
316
data, stat = zk.get("/secure/config")
317
print(f"Secure data: {data}")
318
319
# Update ACLs
320
read_only_acl = make_digest_acl("admin", "secret", read=True)
321
zk.set_acls("/secure/config", read_only_acl, version=stat.aversion)
322
323
except AuthFailedError:
324
print("Authentication failed - check credentials")
325
finally:
326
zk.stop()
327
```
328
329
### Multi-User Access Control
330
331
```python
332
from kazoo.client import KazooClient
333
from kazoo.security import make_digest_acl_credential, ACL, Id, Permissions
334
335
zk = KazooClient()
336
zk.start()
337
338
try:
339
# Create credentials for different users
340
admin_cred = make_digest_acl_credential("admin", "admin_pass")
341
user_cred = make_digest_acl_credential("user", "user_pass")
342
readonly_cred = make_digest_acl_credential("readonly", "readonly_pass")
343
344
# Create multi-user ACL
345
multi_user_acl = [
346
ACL(Permissions.ALL, Id("digest", admin_cred)), # Admin: full access
347
ACL(Permissions.READ | Permissions.WRITE, Id("digest", user_cred)), # User: read/write
348
ACL(Permissions.READ, Id("digest", readonly_cred)), # ReadOnly: read only
349
ACL(Permissions.READ, Id("ip", "192.168.1.0/24")) # Network: read from LAN
350
]
351
352
# Authenticate as admin
353
zk.add_auth("digest", "admin:admin_pass")
354
355
# Create node with multi-user access
356
zk.create("/shared/resource", b"shared data", acl=multi_user_acl, makepath=True)
357
358
# View current ACLs
359
acls, stat = zk.get_acls("/shared/resource")
360
print(f"Node has {len(acls)} ACL entries")
361
for acl in acls:
362
print(f" {acl.id.scheme}:{acl.id.id} -> permissions: {acl.perms}")
363
364
finally:
365
zk.stop()
366
```
367
368
### SSL/TLS Configuration Example
369
370
```python
371
from kazoo.client import KazooClient
372
373
# Configure SSL connection
374
zk = KazooClient(
375
hosts='secure-zk1:2282,secure-zk2:2282', # SSL port
376
use_ssl=True,
377
certfile='/path/to/client.pem', # Client certificate
378
keyfile='/path/to/client-key.pem', # Client private key
379
keyfile_password='key_password', # Key password if encrypted
380
ca='/path/to/ca.pem' # CA certificate
381
)
382
383
try:
384
zk.start()
385
print("Secure connection established")
386
387
# Use secure connection for operations
388
zk.create("/secure", b"encrypted data", makepath=True)
389
390
finally:
391
zk.stop()
392
```
393
394
### SASL/Kerberos Authentication Example
395
396
```python
397
from kazoo.client import KazooClient
398
399
# Configure SASL authentication
400
sasl_options = {
401
'mechanism': 'GSSAPI',
402
'service': 'zookeeper',
403
'principal': 'zkclient/hostname@EXAMPLE.COM'
404
}
405
406
zk = KazooClient(
407
hosts='kerb-zk1:2181,kerb-zk2:2181',
408
sasl_options=sasl_options,
409
auth_data=[('sasl', 'zkclient@EXAMPLE.COM')]
410
)
411
412
try:
413
zk.start()
414
print("SASL authentication successful")
415
416
# Create node accessible to SASL principal
417
sasl_acl = [ACL(Permissions.ALL, Id("sasl", "zkclient@EXAMPLE.COM"))]
418
zk.create("/sasl-protected", b"kerberos data", acl=sasl_acl, makepath=True)
419
420
finally:
421
zk.stop()
422
```
423
424
### Permission Testing Example
425
426
```python
427
from kazoo.client import KazooClient
428
from kazoo.security import make_digest_acl, Permissions
429
from kazoo.exceptions import NoAuthError
430
431
# Test different permission levels
432
def test_permissions():
433
# Create admin client
434
admin_zk = KazooClient()
435
admin_zk.start()
436
admin_zk.add_auth("digest", "admin:secret")
437
438
# Create user client
439
user_zk = KazooClient()
440
user_zk.start()
441
user_zk.add_auth("digest", "user:password")
442
443
try:
444
# Admin creates node with user read-only access
445
user_acl = make_digest_acl("user", "password", read=True)
446
admin_zk.create("/readonly", b"test data", acl=user_acl, makepath=True)
447
448
# User can read
449
data, stat = user_zk.get("/readonly")
450
print(f"User read: {data}")
451
452
# User cannot write (will raise NoAuthError)
453
try:
454
user_zk.set("/readonly", b"modified")
455
print("ERROR: User should not be able to write!")
456
except NoAuthError:
457
print("Correct: User cannot write to read-only node")
458
459
finally:
460
admin_zk.stop()
461
user_zk.stop()
462
463
test_permissions()
464
```