Purpose: Site Replication enables synchronization of Identity and Access Management (IAM) configuration and bucket metadata across multiple geographically distributed MinIO clusters. This feature ensures that users, policies, groups, service accounts, and bucket configurations remain consistent across all participating sites, allowing for disaster recovery and multi-region deployments with unified identity management.
Scope: This document covers the site replication subsystem, focusing on IAM and bucket metadata synchronization. For object-level data replication between buckets, see Bucket Replication. For the underlying IAM system being replicated, see Identity and Access Management. For peer-to-peer communication mechanisms used by site replication, see Distributed Coordination.
The site replication system (SiteReplicationSys) maintains a federation of MinIO clusters where IAM changes on any cluster are automatically propagated to all other clusters in near real-time. Each cluster maintains its own storage but shares a common IAM configuration.
Site Replication Flow Diagram
Sources: cmd/site-replication.go199-210 cmd/iam.go86-112
The SiteReplicationSys struct manages all site replication operations:
| Field | Type | Purpose |
|---|---|---|
enabled | bool | Whether site replication is active |
state | srState | Current replication state including peer list |
iamMetaCache | srIAMCache | Cache for IAM metadata synchronization |
The state is persisted at the path defined by getSRStateFilePath() which returns minioConfigPrefix + "/site-replication/state.json".
Sources: cmd/site-replication.go199-210 cmd/site-replication.go174-176
Site Replication State Data Model
The state contains:
site-replicator-0 service accountSources: cmd/site-replication.go211-229 cmd/site-replication.go54-61
The AddPeerClusters function orchestrates adding clusters to the site replication configuration:
Peer Cluster Addition Sequence
Key validation steps before enabling replication:
Sources: cmd/site-replication.go396-611 cmd/site-replication.go685-712
A special service account siteReplicatorSvcAcc (value: "site-replicator-0") is created during setup:
Service Account Creation and Distribution
This service account:
site-replicator-0) on all clustersallowSiteReplicatorAccount flag in newServiceAccountOptsSources: cmd/site-replication.go348-351 cmd/site-replication.go479-499
The IAMChangeHook function is the central mechanism for replicating IAM changes. It is called whenever an IAM entity is created, updated, or deleted:
IAM Change Propagation Architecture
Sources: cmd/site-replication.go1239-1456
The madmin.SRIAMItem structure encapsulates all IAM change information:
| Field | Type | Description |
|---|---|---|
Type | madmin.SRItemType | Type of IAM item (user, policy, group, etc.) |
Name | string | Name of the entity being changed |
IAMUser | *madmin.SRIAMUser | User creation/deletion details |
IAMPolicy | *madmin.SRIAMPolicy | Policy definition |
PolicyMapping | *madmin.SRPolicyMapping | User/group to policy associations |
GroupInfo | *madmin.SRGroupInfo | Group membership changes |
SvcAccChange | *madmin.SRSvcAccChange | Service account operations |
STSCredential | *madmin.SRSTSCredential | STS temporary credentials |
UpdatedAt | time.Time | Timestamp of change |
Example call sites:
User Deletion:
// cmd/admin-handlers-users.go:93-100
replLogIf(ctx, globalSiteReplicationSys.IAMChangeHook(ctx, madmin.SRIAMItem{
Type: madmin.SRIAMItemIAMUser,
IAMUser: &madmin.SRIAMUser{
AccessKey: accessKey,
IsDeleteReq: true,
},
UpdatedAt: UTCNow(),
}))
Service Account Creation:
// cmd/admin-handlers-users.go:761-778
replLogIf(ctx, globalSiteReplicationSys.IAMChangeHook(ctx, madmin.SRIAMItem{
Type: madmin.SRIAMItemSvcAcc,
SvcAccChange: &madmin.SRSvcAccChange{
Create: &madmin.SRSvcAccCreate{
Parent: newCred.ParentUser,
AccessKey: newCred.AccessKey,
SecretKey: newCred.SecretKey,
Groups: newCred.Groups,
Claims: opts.claims,
SessionPolicy: madmin.SRSessionPolicy(createReq.Policy),
Status: auth.AccountOn,
},
},
UpdatedAt: updatedAt,
}))
Sources: cmd/admin-handlers-users.go93-100 cmd/admin-handlers-users.go761-778 cmd/site-replication.go1239-1456
The IAMChangeHook function distributes changes to all peer clusters:
IAM Change Replication Sequence
The replication process:
concurrentReplicateIAMItem() to fan out to all peers in parallelSRPeerReplicateIAMItem handleritem.Type:
SRIAMItemIAMUser → PeerAddUserHandler() or PeerDeleteUserHandler()SRIAMItemPolicy → PeerAddPolicyHandler()SRIAMItemGroupInfo → PeerGroupInfoHandler()SRIAMItemSvcAcc → PeerSvcAccChangeHandler()SRIAMItemSTSAcc → PeerSTSAccHandler()SRIAMItemPolicyMapping → PeerPolicyMappingHandler()Sources: cmd/site-replication.go1239-1456 cmd/admin-handlers-site-replication.go148-210
Site replication also synchronizes bucket-level operations and metadata across clusters.
The MakeBucketHook function replicates bucket creation:
Bucket Creation Replication Flow
Key features:
Sources: cmd/site-replication.go797-893
The BucketMetaHook function replicates bucket metadata changes:
Bucket Metadata Synchronization
The metadata hook handles:
ReplicateILMExpiry is enabled)Sources: cmd/site-replication.go1051-1210 cmd/admin-handlers-site-replication.go228-331
The site replication system exposes several admin API endpoints:
| Endpoint | Method | Handler | Purpose |
|---|---|---|---|
/minio/admin/v3/site-replication/add | POST | SiteReplicationAdd | Add peer clusters to replication |
/minio/admin/v3/site-replication/join | PUT | SRPeerJoin | Internal: peer joins replication |
/minio/admin/v3/site-replication/iam-item | PUT | SRPeerReplicateIAMItem | Replicate IAM change to peer |
/minio/admin/v3/site-replication/bucket-ops | PUT | SRPeerBucketOps | Replicate bucket operation |
/minio/admin/v3/site-replication/bucket-meta | PUT | SRPeerReplicateBucketItem | Replicate bucket metadata |
/minio/admin/v3/site-replication/info | GET | SiteReplicationInfo | Get replication status |
/minio/admin/v3/site-replication/status | GET | SiteReplicationStatus | Get detailed peer status |
/minio/admin/v3/site-replication/edit | PUT | SiteReplicationEdit | Modify replication config |
/minio/admin/v3/site-replication/remove | PUT | SiteReplicationRemove | Remove peer from replication |
Sources: cmd/admin-handlers-site-replication.go39-447
All cross-cluster API calls use the special site-replicator-0 service account:
Cross-Cluster Authentication
The getAdminClient() function creates an authenticated admin client for peer communication:
// cmd/site-replication.go:1562-1594
func (c *SiteReplicationSys) getAdminClient(ctx context.Context, deploymentID string) (*madmin.AdminClient, error) {
// Get peer info from state
peerInfo := c.state.Peers[deploymentID]
// Use globalSiteReplicatorCred for authentication
secretKey, err := globalSiteReplicatorCred.Get(ctx)
// Create admin client
return getAdminClient(peerInfo.Endpoint,
c.state.ServiceAccountAccessKey,
secretKey)
}
Sources: cmd/site-replication.go1562-1594 cmd/sts-handlers.go244-255
The site replication system includes healing mechanisms to recover from failures or synchronize newly added clusters.
Site Replication Healing Process
The healing routine periodically:
Sources: cmd/site-replication.go232-255 cmd/site-replication.go2678-2862
When new clusters are added, syncToAllPeers() performs an initial synchronization:
Initial Synchronization Sequence
This ensures that a newly added cluster receives:
Sources: cmd/site-replication.go1901-2074
All peer clusters must have identical Identity Provider (IDP) settings to ensure consistent authentication behavior.
IDP Settings Validation Flow
The validation process:
SRPeerGetIDPSettings APIreflect.DeepEqual()Example validation code:
// cmd/site-replication.go:705-709
for i := 1; i < len(s); i++ {
if !reflect.DeepEqual(s[i], s[0]) {
return errSRIAMConfigMismatch(peers[0].Name, peers[i].Name, s[0], s[i])
}
}
Sources: cmd/site-replication.go685-712 cmd/site-replication.go669-683
The site replication system defines specific error types:
| Error | Code | Description |
|---|---|---|
errSRCannotJoin | ErrSiteReplicationInvalidRequest | Cluster already in replication |
errSRDuplicateSites | ErrSiteReplicationInvalidRequest | Duplicate deployment IDs provided |
errSRSelfNotFound | ErrSiteReplicationInvalidRequest | Current cluster not in peer list |
errSRPeerNotFound | ErrSiteReplicationInvalidRequest | Specified peer not found |
errSRNotEnabled | ErrSiteReplicationInvalidRequest | Site replication not configured |
errSRBackendIssue | ErrSiteReplicationBackendIssue | Storage backend error |
errSRIAMError | ErrSiteReplicationIAMError | IAM operation failed |
errSRBucketConfigError | ErrSiteReplicationBucketConfigError | Bucket config error |
Sources: cmd/site-replication.go64-173
The SiteReplicationStatus API provides detailed status information:
Site Replication Status Data Model
The status API returns:
Sources: cmd/site-replication.go2152-2574
Every IAM mutation in the codebase includes a site replication hook:
User Operations:
CreateUser() → IAMChangeHook() with SRIAMItemIAMUser cmd/admin-handlers-users.go538-546DeleteUser() → IAMChangeHook() with IsDeleteReq: true cmd/admin-handlers-users.go93-100SetUserStatus() → IAMChangeHook() with status change cmd/admin-handlers-users.go425-435Policy Operations:
SetPolicy() → IAMChangeHook() with SRIAMItemPolicy cmd/site-replication.go1456DeletePolicy() → IAMChangeHook() with IsDeleteReq: trueAttachPolicy() → IAMChangeHook() with SRIAMItemPolicyMappingGroup Operations:
AddUsersToGroup() → IAMChangeHook() with SRIAMItemGroupInfo cmd/admin-handlers-users.go297-303RemoveUsersFromGroup() → IAMChangeHook() with group updateSetGroupStatus() → IAMChangeHook() with status change cmd/admin-handlers-users.go387-397Service Account Operations:
NewServiceAccount() → IAMChangeHook() with SRIAMItemSvcAcc (if not root account) cmd/admin-handlers-users.go761-778UpdateServiceAccount() → IAMChangeHook() with update details cmd/admin-handlers-users.go887-901DeleteServiceAccount() → IAMChangeHook() with delete requestSources: cmd/admin-handlers-users.go93-100 cmd/admin-handlers-users.go538-546 cmd/admin-handlers-users.go761-778
The STS (Security Token Service) system also integrates with site replication:
// cmd/sts-handlers.go:349-361
// Call hook for site replication.
if cred.ParentUser != globalActiveCred.AccessKey {
replLogIf(ctx, globalSiteReplicationSys.IAMChangeHook(ctx, madmin.SRIAMItem{
Type: madmin.SRIAMItemSTSAcc,
STSCredential: &madmin.SRSTSCredential{
AccessKey: cred.AccessKey,
SecretKey: cred.SecretKey,
SessionToken: cred.SessionToken,
ParentUser: cred.ParentUser,
},
UpdatedAt: updatedAt,
}))
}
Note: Root user's STS credentials are not replicated (as indicated by the check cred.ParentUser != globalActiveCred.AccessKey).
Sources: cmd/sts-handlers.go349-361 cmd/sts-handlers.go589-600
| Function | File | Purpose |
|---|---|---|
AddPeerClusters() | cmd/site-replication.go:397-611 | Add new clusters to replication setup |
PeerJoinReq() | cmd/site-replication.go:614-665 | Handle join request from coordinator |
IAMChangeHook() | cmd/site-replication.go:1239-1456 | Replicate IAM change to all peers |
MakeBucketHook() | cmd/site-replication.go:797-893 | Replicate bucket creation |
DeleteBucketHook() | cmd/site-replication.go:895-950 | Replicate bucket deletion |
BucketMetaHook() | cmd/site-replication.go:1051-1210 | Replicate bucket metadata changes |
validateIDPSettings() | cmd/site-replication.go:685-712 | Ensure IDP config matches across peers |
syncToAllPeers() | cmd/site-replication.go:1901-2074 | Initial sync of all entities |
healIAMSystem() | cmd/site-replication.go:2678-2862 | Background healing routine |
getAdminClient() | cmd/site-replication.go:1562-1594 | Get authenticated client for peer |
// cmd/site-replication.go:348-351
const (
// Access key of service account used for perform cluster-replication
// operations.
siteReplicatorSvcAcc = "site-replicator-0"
)
This constant defines the fixed access key used for all cross-cluster authentication.
Sources: cmd/site-replication.go348-351 cmd/site-replication.go397-2862
To set up site replication between three clusters:
site-replicator-0 account is automatically created with synchronized credentialsThe coordinator cluster should be the one with existing data (if any). All other clusters should be empty to avoid conflicts.
Sources: cmd/site-replication.go396-611
Refresh this wiki