matrix-corporal
acts upon a so-called policy - a JSON document telling it what the state of the Matrix server should be like.
Policies are loaded into matrix-corporal
through the help of a policy provider.
The policy is a JSON document that looks like this:
{
"schemaVersion": 1,
"identificationStamp": null,
"flags": {
"allowCustomUserDisplayNames": false,
"allowCustomUserAvatars": false,
"allowCustomPassthroughUserPasswords": false,
"forbidRoomCreation": false,
"forbidEncryptedRoomCreation": false,
"forbidUnencryptedRoomCreation": false
},
"managedRoomIds": [
"!roomA:example.com",
"!roomB:example.com",
],
"hooks": [
{
"id": "custom-hook-to-prevent-banning",
"eventType": "beforeAnyRequest",
"matchRules": [
{"type": "route", "regex": "^/_matrix/client/r0/rooms/([^/]+)/ban"},
{"type": "method", "regex": "POST"}
],
"action": "reject",
"responseStatusCode": 403,
"rejectionErrorCode": "M_FORBIDDEN",
"rejectionErrorMessage": "Banning is forbidden on this server. We're nice like that!"
},
{
"id": "custom-hook-to-reject-room-creation-once-in-a-while",
"eventType": "beforeAuthenticatedRequest",
"matchRules": [
{"type": "route", "regex": "^/_matrix/client/r0/createRoom"}
],
"action": "consult.RESTServiceURL",
"RESTServiceURL": "http://hook-rest-service:8080/reject/with-33-percent-chance",
"RESTServiceRequestHeaders": {
"Authorization": "Bearer SOME_TOKEN"
},
"RESTServiceContingencyHook": {
"action": "reject",
"responseStatusCode": 403,
"rejectionErrorCode": "M_FORBIDDEN",
"rejectionErrorMessage": "REST service down. Rejecting you to be on the safe side"
}
},
{
"id": "custom-hook-to-capture-room-creation-details",
"eventType": "afterAuthenticatedRequest",
"matchRules": [
{"type": "route", "regex": "^/_matrix/client/r0/createRoom"}
],
"action": "consult.RESTServiceURL",
"RESTServiceURL": "http://hook-rest-service:8080/dump",
"RESTServiceRequestHeaders": {
"Authorization": "Bearer SOME_TOKEN"
}
}
],
"users": [
{
"id": "@john:example.com",
"active": true,
"authType": "plain",
"authCredential": "PaSSw0rD",
"displayName": "John",
"avatarUri": "https://example.com/john.jpg",
"joinedRooms": [
{"roomId": "!roomA:example.com", "powerLevel": 0},
{"roomId": "!roomB:example.com", "powerLevel": 50}
],
"forbidRoomCreation": true
},
{
"id": "@peter:example.com",
"active": true,
"authType": "sha1",
"authCredential": "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3",
"displayName": "Just Peter",
"avatarUri": "",
"joinedRooms": [
{"roomId": "!roomB:example.com", "powerLevel": 0}
],
"forbidRoomCreation": false,
"forbidEncryptedRoomCreation": true
},
{
"id": "@george:example.com",
"active": true,
"authType": "rest",
"authCredential": "https://intranet.example.com/_matrix-internal/identity/v1/check_credentials",
"displayName": "Georgey",
"avatarUri": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==",
"joinedRooms": [
{"roomId": "!roomA:example.com", "powerLevel": 25},
{"roomId": "!roomB:example.com", "powerLevel": 50}
],
"forbidRoomCreation": false,
"forbidUnencryptedRoomCreation": true
}
]
}
A policy contains the following fields:
-
schemaVersion
- tells which schema version this policy is using. This field will be useful in case we introduce backward-incompatible changes in the future. The currentschemaVersion
is2
. -
identificationStamp
- an optionalstring
value provided by you to help you identify this policy. For now, it's only used for debugging purposes, but in the future we might suppress reconciliation if we fetch a policy which has the same stamp as the one last used for reconciliation. So, if you provide this value at all, make sure it gets a new value, at least whenever the policy changes. -
flags
- a list of flags tellingmatrix-corporal
what other global restrictions to apply. See flags below. -
managedRoomIds
- a list of room identifiers (like!room:server
) thatmatrix-corporal
is allowed to manage forusers
. Any room that is not listed here will be left untouched. -
hooks
- a list of event hooks and their configuration. -
users
- a list of users and their configuration (see user policy fields below). Any server user that is not listed here will be left untouched.
The following policy flags are supported:
-
allowCustomUserDisplayNames
(true
orfalse
, defaults tofalse
) - controls whether users are allowed to set custom display names. By default, users are created with the display name specified in the policy. Whether they're able to set a custom one by themselves later on is controlled by this flag. -
allowCustomUserAvatars
(true
orfalse
, defaults tofalse
) - controls whether users are allowed to set custom avatar images. By default, users are created with the avatar image specified in the policy. Whether they're able to set a custom one by themselves later on is controlled by this flag. -
allowCustomPassthroughUserPasswords
(true
orfalse
, defaults tofalse
) - controls whether users withauthType=passthrough
can set custom passwords. By default, such users are created with an initial password as defined inauthCredential
. Whether they can change their homeserver password later or not is controlled by this flag. -
allowUnauthenticatedPasswordResets
(true
orfalse
, defaults tofalse
) - controls whether unauthenticated users (no access token) can reset their password using the/_matrix/client/r0/account/password
API. They prove their identity by verifying 3pids before sending the unauthenticated request.matrix-corporal
doesn't reach into theauth
request data for this endpoint and can't figure out who it is and whether it's a policy-managed user or not and what policy it should apply. Should you enable this option, all users will be allowed to reset their Synapse-stored password. If all your users are managed bymatrix-corporal
and have passwords in its policy, you'd better not enable this. -
forbidRoomCreation
(true
orfalse
, defaults tofalse
) - controls whether users are forbidden from creating rooms. TheforbidRoomCreation
User policy field takes precedence over this. This is just a global default in case the user policy does not specify a value. -
forbidEncryptedRoomCreation
(true
orfalse
, defaults tofalse
) - controls whether users are forbidden from creating encrypted rooms and from switching unencrypted rooms to encrypted subsequently. TheforbidEncryptedRoomCreation
User policy field takes precedence over this. This is just a global default in case the user policy does not specify a value. Also, see the note about encryption below. -
forbidUnencryptedRoomCreation
(true
orfalse
, defaults tofalse
) - controls whether users are forbidden from creating unencrypted rooms. TheforbidUnencryptedRoomCreation
User policy field takes precedence over this. This is just a global default in case the user policy does not specify a value. Also, see the note about encryption below. -
allow3pidLogin
(true
orfalse
, defaults tofalse
) - controls whether users would be able to log in with 3pid (third-party identifiers) associated with their user account (email address / phone number). If enabled, we let such login requests requests pass and go directly to the homeserver. This has some security implications - any checks matrix-corporal would have normally done (checking theactive
status in the user policy, etc.) are skipped.
The users
field in the policy fields (above) contains a list of users and the configuration that applies to each user (besides the global policy flags).
A user policy object looks like this:
{
"id": "@john:example.com",
"active": true,
"authType": "plain",
"authCredential": "PaSSw0rD",
"displayName": "John",
"avatarUri": "https://example.com/john.jpg",
"joinedRooms": [
{"roomId": "!roomA:example.com", "powerLevel": 0},
{"roomId": "!roomB:example.com", "powerLevel": 50}
],
"forbidRoomCreation": false,
"forbidEncryptedRoomCreation": false,
"forbidUnencryptedRoomCreation": false
}
A user-policy contains the following fields:
-
id
- the full Matrix id of the user -
active
(true
orfalse
) - tells whether the user's account is active. Iffalse
: the account will not be created on the Matrix server or it will be disabled, if it exists. Access to disabled accounts is revoked immediately (destroying access tokens). -
authType
- the type of authentication to use for this user. See User Authentication for more information. -
authCredential
- the authentication credential to use for this user. This has a different meaning depending on the type of authenticator being used (specified in theauthType
field). See User Authentication for more information. -
displayName
- the name of this user. New accounts will always be created with the name specified in the policy. The display name on the Matrix server is kept in sync with the policy (and any edits by the user are prevented), unless theallowCustomUserDisplayNames
flag is set totrue
(see flags above). -
avatarUri
- the avatar image of this user. It can be a public remote URL or a data URI (e.g.data:image/png;base64,DATA_GOES_HERE
). New accounts will always be created with the avatar specified in the policy. The avatar on the Matrix server is kept in sync with the policy (and any edits by the user are prevented), unless theallowCustomUserAvatars
flag is set totrue
(see flags above). For performance reasons, avatar URLs are not re-fetched unless the URL changes, so make sure avatar URLs change when the underlying data changes. -
joinedRooms
- a list of room definitions (e.g.{"roomId": "!room:server", "powerLevel": 25}
) that the user is part of:- The user will be auto-joined to any rooms listed here, unless already joined. If the user happens to be joined to a room which is not listed here, but appears in the top-level
managedRoomIds
field, the user will be kicked out of that room. The user can be part of any number of other room which are not listed injoinedRooms
, as long as they are also not listed inmanagedRoomIds
. - The
powerLevel
field can be omitted, in which case it will default to0
. - A
powerLevel
value of0
does not mean "do not manage user levels", but "set the user's power level to 0". The default power level for users that were joined to rooms was0
anyway (although rooms can be configured to use a different value). Unless you've changed the default room power level or individual power levels for users manually, using a0
power level value should be backward-compatible. - You can use any power level you'd like, as long as it's not higher than what the
matrix-corporal
user has. - Using a power level that equals the power level of the
matrix-corporal
user means that demotion will not be possible. Users of equal power cannot demote one another.
- The user will be auto-joined to any rooms listed here, unless already joined. If the user happens to be joined to a room which is not listed here, but appears in the top-level
-
forbidRoomCreation
(true
orfalse
, defaults tofalse
) - controls whether this user is forbidden from creating rooms. If this field is omitted, the globalforbidRoomCreation
flag is used as a fallback. -
forbidEncryptedRoomCreation
(true
orfalse
, defaults tofalse
) - controls whether this user is forbidden from creating encrypted rooms and from switching unencrypted rooms to encrypted subsequently. If this field is omitted, the globalforbidEncryptedRoomCreation
flag is used as a fallback. Also, see the note about encryption below. -
forbidUnencryptedRoomCreation
(true
orfalse
, defaults tofalse
) - controls whether this user is forbidden from creating unencrypted rooms. If this field is omitted, the globalforbidUnencryptedRoomCreation
flag is used as a fallback. Also, see the note about encryption below.
We support forbidEncryptedRoomCreation
and forbidUnencryptedRoomCreation
flags both as a global level flag and as a user policy flag.
Preventing encrypted or unencrypted rooms from being created does not guarantee that users will not end up being part of such rooms. If your server is a federating one, your users may end up in rooms which don't respect these value.
You can generate the matrix-corporal policy file directly (from your own software), or with the help of some other tool.
If you're using LDAP, you may find this tool useful: cmuller/ldap_matrix - Matrix Corporal Policy Specification Using LDAP Groups