0
# User Management
1
2
PyMilvus provides comprehensive authentication, authorization, and access control capabilities including user management, role-based access control (RBAC), privilege groups, and resource management. This enables secure multi-tenant deployments with fine-grained permissions.
3
4
## User Operations
5
6
### Create User
7
8
```python { .api }
9
from pymilvus import MilvusClient
10
11
client = MilvusClient()
12
13
def create_user(
14
user_name: str,
15
password: str,
16
timeout: Optional[float] = None
17
) -> None
18
```
19
20
```python { .api }
21
# Create new user
22
client.create_user("data_analyst", "secure_password_123")
23
24
# Create user with special characters in password
25
client.create_user("ml_engineer", "P@ssw0rd!2024")
26
27
# Multiple user creation
28
users_to_create = [
29
("reader_user", "read_only_pass"),
30
("writer_user", "write_access_pass"),
31
("admin_user", "admin_secure_pass")
32
]
33
34
for username, password in users_to_create:
35
try:
36
client.create_user(username, password)
37
print(f"✓ Created user: {username}")
38
except Exception as e:
39
print(f"✗ Failed to create user {username}: {e}")
40
```
41
42
### User Information
43
44
```python { .api }
45
def list_users(
46
timeout: Optional[float] = None
47
) -> List[str]
48
49
def describe_user(
50
user_name: str,
51
timeout: Optional[float] = None
52
) -> Dict[str, Any]
53
```
54
55
```python { .api }
56
# List all users
57
users = client.list_users()
58
print(f"System users: {users}")
59
60
# Get detailed user information
61
user_info = client.describe_user("data_analyst")
62
print(f"User info: {user_info}")
63
64
# Check user roles and privileges
65
for user in users:
66
try:
67
info = client.describe_user(user)
68
roles = info.get('roles', [])
69
print(f"User {user}: roles = {roles}")
70
except Exception as e:
71
print(f"Error getting info for {user}: {e}")
72
```
73
74
### Password Management
75
76
```python { .api }
77
def update_password(
78
user_name: str,
79
old_password: str,
80
new_password: str,
81
timeout: Optional[float] = None
82
) -> None
83
84
def reset_password(
85
user_name: str,
86
new_password: str,
87
timeout: Optional[float] = None
88
) -> None
89
```
90
91
```python { .api }
92
# Update password (requires current password)
93
client.update_password("data_analyst", "old_password", "new_secure_password")
94
95
# Reset password (admin operation, doesn't require old password)
96
client.reset_password("data_analyst", "admin_reset_password")
97
98
# Password update with error handling
99
def safe_password_update(username: str, old_pass: str, new_pass: str):
100
"""Safely update password with validation"""
101
102
# Basic password validation
103
if len(new_pass) < 8:
104
raise ValueError("Password must be at least 8 characters")
105
106
if not any(c.isupper() for c in new_pass):
107
raise ValueError("Password must contain uppercase letter")
108
109
if not any(c.isdigit() for c in new_pass):
110
raise ValueError("Password must contain digit")
111
112
try:
113
client.update_password(username, old_pass, new_pass)
114
print(f"Password updated for user: {username}")
115
return True
116
except Exception as e:
117
print(f"Password update failed: {e}")
118
return False
119
120
# Usage
121
success = safe_password_update("data_analyst", "old_pass", "NewSecure123!")
122
```
123
124
### Delete User
125
126
```python { .api }
127
def drop_user(
128
user_name: str,
129
timeout: Optional[float] = None
130
) -> None
131
```
132
133
```python { .api }
134
# Delete single user
135
client.drop_user("obsolete_user")
136
137
# Bulk user deletion with confirmation
138
def bulk_delete_users(usernames: List[str], confirm: bool = False):
139
"""Safely delete multiple users"""
140
141
if not confirm:
142
print("This will delete the following users:")
143
for username in usernames:
144
print(f" - {username}")
145
print("Set confirm=True to proceed")
146
return
147
148
deleted_count = 0
149
for username in usernames:
150
try:
151
# Check if user exists first
152
users = client.list_users()
153
if username in users:
154
client.drop_user(username)
155
deleted_count += 1
156
print(f"✓ Deleted user: {username}")
157
else:
158
print(f"- User {username} doesn't exist")
159
except Exception as e:
160
print(f"✗ Failed to delete {username}: {e}")
161
162
print(f"Deleted {deleted_count}/{len(usernames)} users")
163
164
# Usage
165
bulk_delete_users(["temp_user1", "test_user2"], confirm=True)
166
```
167
168
## Role Management
169
170
### Create and Manage Roles
171
172
```python { .api }
173
def create_role(
174
role_name: str,
175
timeout: Optional[float] = None
176
) -> None
177
178
def drop_role(
179
role_name: str,
180
timeout: Optional[float] = None
181
) -> None
182
183
def list_roles(
184
timeout: Optional[float] = None
185
) -> List[str]
186
187
def describe_role(
188
role_name: str,
189
timeout: Optional[float] = None
190
) -> Dict[str, Any]
191
```
192
193
```python { .api }
194
# Create roles for different access levels
195
roles_to_create = [
196
"data_reader", # Read-only access
197
"data_writer", # Read + write access
198
"collection_admin", # Collection management
199
"system_admin" # Full system access
200
]
201
202
for role in roles_to_create:
203
try:
204
client.create_role(role)
205
print(f"✓ Created role: {role}")
206
except Exception as e:
207
print(f"✗ Role creation failed for {role}: {e}")
208
209
# List and describe roles
210
roles = client.list_roles()
211
print(f"Available roles: {roles}")
212
213
for role in roles:
214
role_info = client.describe_role(role)
215
print(f"Role {role}: {role_info}")
216
```
217
218
### Role Assignment
219
220
```python { .api }
221
def grant_role(
222
user_name: str,
223
role_name: str,
224
timeout: Optional[float] = None
225
) -> None
226
227
def revoke_role(
228
user_name: str,
229
role_name: str,
230
timeout: Optional[float] = None
231
) -> None
232
```
233
234
```python { .api }
235
# Assign roles to users
236
role_assignments = {
237
"analyst1": ["data_reader"],
238
"analyst2": ["data_reader", "data_writer"],
239
"admin1": ["collection_admin", "system_admin"],
240
"service_user": ["data_writer"]
241
}
242
243
for username, roles in role_assignments.items():
244
for role in roles:
245
try:
246
client.grant_role(username, role)
247
print(f"✓ Granted {role} to {username}")
248
except Exception as e:
249
print(f"✗ Failed to grant {role} to {username}: {e}")
250
251
# Revoke role from user
252
client.revoke_role("analyst1", "data_writer")
253
print("Revoked data_writer role from analyst1")
254
```
255
256
## Privilege Management
257
258
### Grant and Revoke Privileges
259
260
```python { .api }
261
def grant_privilege(
262
role_name: str,
263
object_type: str,
264
privilege: str,
265
object_name: str,
266
db_name: str = "",
267
timeout: Optional[float] = None
268
) -> None
269
270
def revoke_privilege(
271
role_name: str,
272
object_type: str,
273
privilege: str,
274
object_name: str,
275
db_name: str = "",
276
timeout: Optional[float] = None
277
) -> None
278
```
279
280
**Object Types:**
281
- `"Global"`: System-level privileges
282
- `"Collection"`: Collection-specific privileges
283
- `"User"`: User management privileges
284
285
**Common Privileges:**
286
- `"Insert"`, `"Delete"`, `"Upsert"`: Data modification
287
- `"Search"`, `"Query"`: Data access
288
- `"IndexUser"`: Index management
289
- `"CollectionAdmin"`: Collection administration
290
- `"DatabaseAdmin"`: Database administration
291
292
```python { .api }
293
# Grant collection-level privileges
294
collection_privileges = [
295
("data_reader", "Collection", "Search", "public_data"),
296
("data_reader", "Collection", "Query", "public_data"),
297
("data_writer", "Collection", "Insert", "user_content"),
298
("data_writer", "Collection", "Delete", "user_content"),
299
("data_writer", "Collection", "Upsert", "user_content"),
300
]
301
302
for role, obj_type, privilege, obj_name in collection_privileges:
303
try:
304
client.grant_privilege(role, obj_type, privilege, obj_name)
305
print(f"✓ Granted {privilege} on {obj_name} to {role}")
306
except Exception as e:
307
print(f"✗ Failed to grant {privilege}: {e}")
308
309
# Grant global privileges
310
client.grant_privilege("collection_admin", "Global", "CreateCollection", "*")
311
client.grant_privilege("collection_admin", "Global", "DropCollection", "*")
312
313
# Grant user management privileges
314
client.grant_privilege("system_admin", "User", "UpdateUser", "*")
315
client.grant_privilege("system_admin", "User", "SelectUser", "*")
316
```
317
318
### Enhanced Privilege Management (V2)
319
320
```python { .api }
321
def grant_privilege_v2(
322
role_name: str,
323
privilege: str,
324
collection_name: str = "*",
325
db_name: str = "",
326
timeout: Optional[float] = None
327
) -> None
328
329
def revoke_privilege_v2(
330
role_name: str,
331
privilege: str,
332
collection_name: str = "*",
333
db_name: str = "",
334
timeout: Optional[float] = None
335
) -> None
336
```
337
338
```python { .api }
339
# V2 privilege management with simplified syntax
340
v2_privileges = [
341
("analyst_role", "Query", "analytics_data"),
342
("analyst_role", "Search", "analytics_data"),
343
("writer_role", "Insert", "content_collection"),
344
("writer_role", "Delete", "content_collection"),
345
("admin_role", "DropCollection", "*"), # Global privilege
346
]
347
348
for role, privilege, collection in v2_privileges:
349
try:
350
client.grant_privilege_v2(role, privilege, collection)
351
print(f"✓ Granted {privilege} on {collection} to {role}")
352
except Exception as e:
353
print(f"✗ V2 privilege grant failed: {e}")
354
```
355
356
## Privilege Groups
357
358
### Privilege Group Management
359
360
```python { .api }
361
def create_privilege_group(
362
group_name: str,
363
timeout: Optional[float] = None
364
) -> None
365
366
def drop_privilege_group(
367
group_name: str,
368
timeout: Optional[float] = None
369
) -> None
370
371
def list_privilege_groups(
372
timeout: Optional[float] = None
373
) -> List[str]
374
```
375
376
```python { .api }
377
# Create privilege groups for common access patterns
378
privilege_groups = [
379
"read_only_group",
380
"content_editor_group",
381
"analytics_group",
382
"admin_group"
383
]
384
385
for group in privilege_groups:
386
try:
387
client.create_privilege_group(group)
388
print(f"✓ Created privilege group: {group}")
389
except Exception as e:
390
print(f"✗ Failed to create group {group}: {e}")
391
392
# List privilege groups
393
groups = client.list_privilege_groups()
394
print(f"Privilege groups: {groups}")
395
```
396
397
### Add and Remove Privileges from Groups
398
399
```python { .api }
400
def add_privileges_to_group(
401
group_name: str,
402
privileges: List[str],
403
timeout: Optional[float] = None
404
) -> None
405
406
def remove_privileges_from_group(
407
group_name: str,
408
privileges: List[str],
409
timeout: Optional[float] = None
410
) -> None
411
```
412
413
```python { .api }
414
# Define privilege sets for different groups
415
group_privileges = {
416
"read_only_group": ["Query", "Search"],
417
"content_editor_group": ["Query", "Search", "Insert", "Delete", "Upsert"],
418
"analytics_group": ["Query", "Search", "IndexUser"],
419
"admin_group": ["Query", "Search", "Insert", "Delete", "Upsert", "CreateCollection", "DropCollection"]
420
}
421
422
# Add privileges to groups
423
for group_name, privileges in group_privileges.items():
424
try:
425
client.add_privileges_to_group(group_name, privileges)
426
print(f"✓ Added {len(privileges)} privileges to {group_name}")
427
except Exception as e:
428
print(f"✗ Failed to add privileges to {group_name}: {e}")
429
430
# Remove specific privileges from group
431
client.remove_privileges_from_group("analytics_group", ["IndexUser"])
432
print("Removed IndexUser privilege from analytics_group")
433
```
434
435
## Database Operations
436
437
### Database Management
438
439
```python { .api }
440
def create_database(
441
db_name: str,
442
timeout: Optional[float] = None
443
) -> None
444
445
def drop_database(
446
db_name: str,
447
timeout: Optional[float] = None
448
) -> None
449
450
def list_databases(
451
timeout: Optional[float] = None
452
) -> List[str]
453
454
def describe_database(
455
db_name: str,
456
timeout: Optional[float] = None
457
) -> Dict[str, Any]
458
```
459
460
```python { .api }
461
# Create databases for different environments
462
environments = ["development", "staging", "production", "analytics"]
463
464
for env in environments:
465
try:
466
client.create_database(env)
467
print(f"✓ Created database: {env}")
468
except Exception as e:
469
print(f"✗ Failed to create database {env}: {e}")
470
471
# List and describe databases
472
databases = client.list_databases()
473
print(f"Available databases: {databases}")
474
475
for db in databases:
476
db_info = client.describe_database(db)
477
print(f"Database {db}: {db_info}")
478
```
479
480
### Database Context Management
481
482
```python { .api }
483
def use_database(
484
db_name: str,
485
timeout: Optional[float] = None
486
) -> None
487
488
def using_database(
489
db_name: str,
490
timeout: Optional[float] = None
491
) -> ContextManager
492
```
493
494
```python { .api }
495
# Switch to specific database
496
client.use_database("production")
497
print("Switched to production database")
498
499
# Use context manager for temporary database switch
500
with client.using_database("analytics"):
501
# Operations in this block use the analytics database
502
collections = client.list_collections()
503
print(f"Analytics collections: {collections}")
504
505
# Back to previous database context
506
collections = client.list_collections()
507
print(f"Production collections: {collections}")
508
```
509
510
### Database Properties
511
512
```python { .api }
513
def alter_database_properties(
514
db_name: str,
515
properties: Dict[str, str],
516
timeout: Optional[float] = None
517
) -> None
518
519
def drop_database_properties(
520
db_name: str,
521
property_keys: List[str],
522
timeout: Optional[float] = None
523
) -> None
524
```
525
526
```python { .api }
527
# Set database properties
528
db_properties = {
529
"description": "Production database for AI applications",
530
"environment": "production",
531
"owner": "ml_team"
532
}
533
534
client.alter_database_properties("production", db_properties)
535
536
# Remove specific properties
537
client.drop_database_properties("production", ["owner"])
538
```
539
540
## Alias Management
541
542
### Collection Aliases
543
544
```python { .api }
545
def create_alias(
546
collection_name: str,
547
alias: str,
548
timeout: Optional[float] = None
549
) -> None
550
551
def drop_alias(
552
alias: str,
553
timeout: Optional[float] = None
554
) -> None
555
556
def alter_alias(
557
collection_name: str,
558
alias: str,
559
timeout: Optional[float] = None
560
) -> None
561
562
def describe_alias(
563
alias: str,
564
timeout: Optional[float] = None
565
) -> Dict[str, Any]
566
567
def list_aliases(
568
collection_name: str,
569
timeout: Optional[float] = None
570
) -> List[str]
571
```
572
573
```python { .api }
574
# Create aliases for collections
575
alias_mappings = {
576
"products_v2": "products_latest",
577
"user_embeddings_2024": "current_embeddings",
578
"search_logs_december": "recent_logs"
579
}
580
581
for collection, alias in alias_mappings.items():
582
try:
583
client.create_alias(collection, alias)
584
print(f"✓ Created alias {alias} -> {collection}")
585
except Exception as e:
586
print(f"✗ Failed to create alias {alias}: {e}")
587
588
# Switch alias to new collection (blue-green deployment)
589
client.alter_alias("products_v3", "products_latest")
590
print("Switched products_latest alias to products_v3")
591
592
# Get alias information
593
alias_info = client.describe_alias("products_latest")
594
print(f"Alias info: {alias_info}")
595
596
# List aliases for collection
597
aliases = client.list_aliases("products_v3")
598
print(f"Aliases for products_v3: {aliases}")
599
```
600
601
## Access Control Patterns
602
603
### Role-Based Access Control Setup
604
605
```python { .api }
606
def setup_rbac_system():
607
"""Setup comprehensive RBAC system"""
608
609
# 1. Create roles
610
roles = {
611
"viewer": "Read-only access to data",
612
"editor": "Read and write access to specific collections",
613
"analyst": "Read access + query capabilities",
614
"admin": "Full administrative access"
615
}
616
617
for role_name, description in roles.items():
618
try:
619
client.create_role(role_name)
620
print(f"✓ Created role: {role_name} - {description}")
621
except Exception as e:
622
print(f"Role {role_name} might already exist: {e}")
623
624
# 2. Create privilege groups
625
groups = ["basic_read", "data_modification", "collection_management", "system_administration"]
626
627
for group in groups:
628
try:
629
client.create_privilege_group(group)
630
except Exception as e:
631
print(f"Group {group} might already exist: {e}")
632
633
# 3. Define privilege sets
634
privilege_sets = {
635
"basic_read": ["Query", "Search"],
636
"data_modification": ["Insert", "Delete", "Upsert"],
637
"collection_management": ["CreateCollection", "DropCollection", "IndexUser"],
638
"system_administration": ["CreateUser", "UpdateUser", "SelectUser", "CreateRole"]
639
}
640
641
# 4. Add privileges to groups
642
for group, privileges in privilege_sets.items():
643
try:
644
client.add_privileges_to_group(group, privileges)
645
print(f"✓ Added {len(privileges)} privileges to {group}")
646
except Exception as e:
647
print(f"Error adding privileges to {group}: {e}")
648
649
# 5. Grant privileges to roles
650
role_privilege_mapping = {
651
"viewer": [("Collection", "Search", "public_*"), ("Collection", "Query", "public_*")],
652
"editor": [
653
("Collection", "Search", "*"), ("Collection", "Query", "*"),
654
("Collection", "Insert", "user_*"), ("Collection", "Delete", "user_*")
655
],
656
"analyst": [
657
("Collection", "Search", "*"), ("Collection", "Query", "*"),
658
("Collection", "IndexUser", "*")
659
],
660
"admin": [("Global", "CreateCollection", "*"), ("Global", "DropCollection", "*")]
661
}
662
663
for role, privileges in role_privilege_mapping.items():
664
for obj_type, privilege, obj_name in privileges:
665
try:
666
client.grant_privilege(role, obj_type, privilege, obj_name)
667
print(f"✓ Granted {privilege} on {obj_name} to {role}")
668
except Exception as e:
669
print(f"Error granting privilege: {e}")
670
671
# Setup RBAC system
672
setup_rbac_system()
673
```
674
675
### Multi-Tenant Access Control
676
677
```python { .api }
678
def setup_tenant_isolation(tenant_name: str):
679
"""Setup isolated access for a tenant"""
680
681
# Create tenant-specific role
682
tenant_role = f"tenant_{tenant_name}"
683
tenant_user = f"user_{tenant_name}"
684
tenant_collections = f"{tenant_name}_*"
685
686
try:
687
# Create role for tenant
688
client.create_role(tenant_role)
689
690
# Grant tenant-specific privileges
691
tenant_privileges = [
692
("Collection", "Search", tenant_collections),
693
("Collection", "Query", tenant_collections),
694
("Collection", "Insert", tenant_collections),
695
("Collection", "Delete", tenant_collections),
696
("Collection", "Upsert", tenant_collections),
697
]
698
699
for obj_type, privilege, obj_name in tenant_privileges:
700
client.grant_privilege(tenant_role, obj_type, privilege, obj_name)
701
702
print(f"✓ Setup access control for tenant: {tenant_name}")
703
704
return {
705
"role": tenant_role,
706
"collections_pattern": tenant_collections,
707
"privileges": [p[1] for p in tenant_privileges]
708
}
709
710
except Exception as e:
711
print(f"✗ Failed to setup tenant {tenant_name}: {e}")
712
return None
713
714
# Setup isolation for multiple tenants
715
tenants = ["acme_corp", "tech_startup", "retail_chain"]
716
tenant_configs = {}
717
718
for tenant in tenants:
719
config = setup_tenant_isolation(tenant)
720
if config:
721
tenant_configs[tenant] = config
722
723
print(f"Configured {len(tenant_configs)} tenant access controls")
724
```
725
726
### Security Audit Functions
727
728
```python { .api }
729
def audit_user_permissions():
730
"""Audit all user permissions and roles"""
731
732
users = client.list_users()
733
roles = client.list_roles()
734
735
audit_report = {
736
"users": {},
737
"roles": {},
738
"summary": {}
739
}
740
741
# Audit users
742
for user in users:
743
try:
744
user_info = client.describe_user(user)
745
audit_report["users"][user] = user_info
746
except Exception as e:
747
audit_report["users"][user] = {"error": str(e)}
748
749
# Audit roles
750
for role in roles:
751
try:
752
role_info = client.describe_role(role)
753
audit_report["roles"][role] = role_info
754
except Exception as e:
755
audit_report["roles"][role] = {"error": str(e)}
756
757
# Generate summary
758
audit_report["summary"] = {
759
"total_users": len(users),
760
"total_roles": len(roles),
761
"users_with_roles": len([u for u in audit_report["users"].values() if u.get("roles")]),
762
"roles_with_privileges": len([r for r in audit_report["roles"].values() if r.get("privileges")])
763
}
764
765
return audit_report
766
767
# Run security audit
768
audit = audit_user_permissions()
769
print(f"Security Audit Summary:")
770
print(f" Total Users: {audit['summary']['total_users']}")
771
print(f" Total Roles: {audit['summary']['total_roles']}")
772
print(f" Users with Roles: {audit['summary']['users_with_roles']}")
773
print(f" Roles with Privileges: {audit['summary']['roles_with_privileges']}")
774
```
775
776
## Using ORM Role Class
777
778
```python { .api }
779
from pymilvus import Role
780
781
# Create Role object
782
role = Role("analytics_team")
783
784
# Role operations
785
def create(self, timeout: Optional[float] = None) -> None
786
def drop(self, timeout: Optional[float] = None) -> None
787
def describe(self, timeout: Optional[float] = None) -> Dict[str, Any]
788
def add_user(self, username: str, timeout: Optional[float] = None) -> None
789
def remove_user(self, username: str, timeout: Optional[float] = None) -> None
790
def grant(self, object_type: str, privilege: str, object_name: str, timeout: Optional[float] = None) -> None
791
def revoke(self, object_type: str, privilege: str, object_name: str, timeout: Optional[float] = None) -> None
792
def list_grants(self, timeout: Optional[float] = None) -> List[Dict[str, Any]]
793
def list_users(self, timeout: Optional[float] = None) -> List[str]
794
```
795
796
```python { .api }
797
# Using Role ORM class
798
analytics_role = Role("analytics_team")
799
800
# Create the role
801
analytics_role.create()
802
803
# Grant privileges using ORM
804
analytics_role.grant("Collection", "Search", "analytics_data")
805
analytics_role.grant("Collection", "Query", "analytics_data")
806
807
# Add users to role
808
analytics_role.add_user("analyst1")
809
analytics_role.add_user("analyst2")
810
811
# List role information
812
grants = analytics_role.list_grants()
813
users = analytics_role.list_users()
814
815
print(f"Role grants: {grants}")
816
print(f"Role users: {users}")
817
818
# Get detailed role information
819
role_info = analytics_role.describe()
820
print(f"Role description: {role_info}")
821
```
822
823
PyMilvus user management provides enterprise-grade authentication and authorization capabilities, enabling secure multi-tenant vector database deployments with fine-grained access control and comprehensive auditing features.