kibana/x-pack/plugins/encrypted_saved_objects
Larry Gregory 639dbbeb19
Migrate audit logging to KP (#67381)
Co-authored-by: Aleh Zasypkin <aleh.zasypkin@gmail.com>
Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
2020-05-28 14:46:42 -04:00
..
server Migrate audit logging to KP (#67381) 2020-05-28 14:46:42 -04:00
kibana.json Allow encrypted saved-object properties to be accessed by end-users (#64941) 2020-05-14 07:59:11 +02:00
README.md [Alerting] Hides the alert SavedObjects type (#66719) 2020-05-21 11:00:15 +01:00

Encrypted Saved Objects

Overview

The purpose of this plugin is to provide a way to encrypt/decrypt attributes on the custom Saved Objects that works with security and spaces filtering as well as performing audit logging.

RFC #2: Encrypted Saved Objects Attributes.

Usage

Follow these steps to use encryptedSavedObjects in your plugin:

  1. Declare encryptedSavedObjects as a dependency in kibana.json:
{
  ...
  "requiredPlugins": ["encryptedSavedObjects"],
  ...
}
  1. Add attributes to be encrypted in mappings.json file for the respective Saved Object type. These attributes should always have a binary type since they'll contain encrypted content as a Base64 encoded string and should never be searchable or analyzed:
{
 "my-saved-object-type": {
   "properties": {
     "name": { "type": "keyword" },
     "mySecret": { "type": "binary" }
   }
 }
}
  1. Register Saved Object type using the provided API at the setup stage:
...
public setup(core: CoreSetup, { encryptedSavedObjects }: PluginSetupDependencies) {
  encryptedSavedObjects.registerType({
    type: 'my-saved-object-type',
    attributesToEncrypt: new Set(['mySecret']),
  });
}
...
  1. For any Saved Object operation that does not require retrieval of decrypted content, use standard REST or programmatic Saved Object API, e.g.:
...
router.get(
  { path: '/some-path', validate: false },
  async (context, req, res) => {
    return res.ok({ 
      body: await context.core.savedObjects.client.create(
        'my-saved-object-type',
         { name: 'some name', mySecret: 'non encrypted secret' }
      ),
    });
  }
);
...
  1. Instantiate an EncryptedSavedObjects client so that you can interact with Saved Objects whose content has been encrypted.
const esoClient = encryptedSavedObjects.getClient();

If your SavedObject type is a hidden type, then you will have to specify it as an included type:

const esoClient = encryptedSavedObjects.getClient({ includedHiddenTypes: ['myHiddenType'] });
  1. To retrieve Saved Object with decrypted content use the dedicated getDecryptedAsInternalUser API method.

Note: As name suggests the method will retrieve the encrypted values and decrypt them on behalf of the internal Kibana user to make it possible to use this method even when user request context is not available (e.g. in background tasks). Hence this method should only be used wherever consumers would otherwise feel comfortable using callAsInternalUser and preferably only as a part of the Kibana server routines that are outside of the lifecycle of a HTTP request that a user has control over.

const savedObjectWithDecryptedContent =  await esoClient.getDecryptedAsInternalUser(
  'my-saved-object-type',
  'saved-object-id'
);

getDecryptedAsInternalUser also accepts the 3rd optional options argument that has exactly the same type as options one would pass to SavedObjectsClient.get. These argument allows to specify namespace property that, for example, is required if Saved Object was created within a non-default space.

Testing

Unit tests

From kibana-root-folder/x-pack, run:

$ node scripts/jest.js

API Integration tests

In one shell, from kibana-root-folder/x-pack:

$ node scripts/functional_tests_server.js --config test/encrypted_saved_objects_api_integration/config.ts

In another shell, from kibana-root-folder/x-pack:

$ node ../scripts/functional_test_runner.js --config test/encrypted_saved_objects_api_integration/config.ts --grep="{TEST_NAME}"