https://discuss.elastic.co/t/how-to-remove-custom-metadata-fields-from-users-and…-roles/266646/2
By design, a PUT on a user does not overwrite their password unless the password (or hash) is in the request body.
That means, that within the NativeUsersStore, the Put will actually perform an update on the underlying document.
Because `metadata` is stored as a nested object, the semantics of that update means that metadata fields are not always removed from the document, even though they are supposed to be (and are for other object types like roles).
To be extra confusing putting a user with `metadata: {}` will preserve all existing metadata, but not specifying `metadata` at all will remove all metadata (and `metadata: null` is not allowed by the rest parser).
We will need to think carefully about how to fix this without breaking existing workflows that rely on the bug.
Examples below:
```
GET /.security/_doc/user-test {}
===
{
"_index": ".security-7",
"_type": "_doc",
"_id": "user-test",
"found": false
}
===
PUT /_security/user/test {}
{"roles":[],"password":"this is a password","metadata":{"test 1":1}}
===
{ "created": true }
===
GET /.security/_doc/user-test {}
===
{
"_index": ".security-7",
"_type": "_doc",
"_id": "user-test",
"_version": 8,
"_seq_no": 23,
"_primary_term": 2,
"found": true,
"_source": {
"username": "test",
"password": "$2a$10$wDDS11yWheRfK2ypdYnlkOvX5Mbh/h38i9Ig9hE.1QHpUY0RlFeLq",
"roles": [],
"full_name": null,
"email": null,
"metadata": { "test 1": 1 },
"enabled": true,
"type": "user"
}
}
===
GET /_security/user/test {}
===
{
"test": {
"username": "test",
"roles": [],
"full_name": null,
"email": null,
"metadata": { "test 1": 1 },
"enabled": true
}
}
===
PUT /_security/user/test {}
{"roles":[],"metadata":{"test 2":2}}
===
{ "created": false }
===
GET /.security/_doc/user-test {}
===
{
"_index": ".security-7",
"_type": "_doc",
"_id": "user-test",
"_version": 9,
"_seq_no": 24,
"_primary_term": 2,
"found": true,
"_source": {
"username": "test",
"password": "$2a$10$wDDS11yWheRfK2ypdYnlkOvX5Mbh/h38i9Ig9hE.1QHpUY0RlFeLq",
"roles": [],
"full_name": null,
"email": null,
"metadata": {
"test 1": 1,
"test 2": 2
},
"enabled": true,
"type": "user"
}
}
===
GET /_security/user/test {}
===
{
"test": {
"username": "test",
"roles": [],
"full_name": null,
"email": null,
"metadata": {
"test 2": 2,
"test 1": 1
},
"enabled": true
}
}
===
PUT /_security/user/test {}
{"roles":[],"metadata":{}}
===
{ "created": false }
===
GET /.security/_doc/user-test {}
===
{
"_index": ".security-7",
"_type": "_doc",
"_id": "user-test",
"_version": 9,
"_seq_no": 24,
"_primary_term": 2,
"found": true,
"_source": {
"username": "test",
"password": "$2a$10$wDDS11yWheRfK2ypdYnlkOvX5Mbh/h38i9Ig9hE.1QHpUY0RlFeLq",
"roles": [],
"full_name": null,
"email": null,
"metadata": {
"test 1": 1,
"test 2": 2
},
"enabled": true,
"type": "user"
}
}
===
GET /_security/user/test {}
===
{
"test": {
"username": "test",
"roles": [],
"full_name": null,
"email": null,
"metadata": {
"test 2": 2,
"test 1": 1
},
"enabled": true
}
}
===
PUT /_security/user/test {}
{"roles":[]}
===
{ "created": false }
===
GET /.security/_doc/user-test {}
===
{
"_index": ".security-7",
"_type": "_doc",
"_id": "user-test",
"_version": 10,
"_seq_no": 25,
"_primary_term": 2,
"found": true,
"_source": {
"username": "test",
"password": "$2a$10$wDDS11yWheRfK2ypdYnlkOvX5Mbh/h38i9Ig9hE.1QHpUY0RlFeLq",
"roles": [],
"full_name": null,
"email": null,
"metadata": null,
"enabled": true,
"type": "user"
}
}
===
GET /_security/user/test {}
===
{
"test": {
"username": "test",
"roles": [],
"full_name": null,
"email": null,
"metadata": {},
"enabled": true
}
}
```