---
title: "Plugins - Getting Started"
slug: "fortanix-dsm-plugins-getting-started"
updated: 2026-03-10T17:18:51Z
published: 2026-03-10T17:18:51Z
canonical: "support.fortanix.com/fortanix-dsm-plugins-getting-started"
---

> ## Documentation Index
> Fetch the complete documentation index at: https://support.fortanix.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Plugins - Getting Started

## 1.0 Introduction

Plugins are a powerful system allowing users and/or applications to securely run sensitive business logic inside the **Fortanix-Data-Security-Manager (DSM)**.

For example, plugins may be used to:

- impose custom, arbitrarily complex access control policies on keys in Fortanix DSM
- require approval from a quorum before a key in Fortanix DSM is used
- ensure that an RSA key in Fortanix DSM may only sign certificates with a particular attribute
- require that a key in Fortanix DSM may only be wrapped with a certificate signed by a particular CA
- implement a secure higher-level cryptographic operation, including custom audit logs, to expose to outside apps

Currently, Lua is the only language supported.

## 2.0 How to Use?

Like apps and security objects, plugins are identified by UUID.

Plugins are invoked using a REST API similar to the cryptographic and key management APIs. *For more information on plugins, refer to the* [*User's Guide: Plugin Library*](/v1/docs/users-guide-plugin-library)*.*

To invoke a plugin, make a POST request to `https://&lt;API endpoint&gt;/sys/v1/plugins/&lt;uuid&gt;`. The POST request body must be either valid JSON or empty.

The plugin may return:

- 200 OK with a JSON response body,
- 204 No Content with empty response body, or
- a 4xx/5xx error with a plain text error message response body.

## 3.0 How to Develop?

Standard plugins define a function `run` that takes a single argument and is called when the plugin gets invoked.

If the POST request body is JSON, the JSON is decoded into a Lua object and passed to `run`. If the POST request body is empty, `nil` is passed to `run`.

For example, if a plugin is invoked with the JSON `{"a":1,"b":[2,3]}`, the function `run` is passed the Lua object `{ a = 1, b = {2, 3} }`.

On success, the function `run` may return `nil` or any encodable Lua object:

- If `run` returns `nil`, the plugin replies with 204 No Content and an empty body.
- Otherwise, the returned object is encoded as JSON, and the plugin replies with 200 OK.

On error, the function `run` returns two results – nil and the error. The error may be:

- a string consisting of the error message, or
- an `Error` object with a custom status code and message. For example `Error.new { status = 404, message = "key not found" }`.

If the error is a string, the plugin replies with 400 Bad Request.

Finally, if `run` raises an exception, the plugin replies with 500 Internal Server Error.

For example, consider the following plugin:

```bash
function run(input)
    if type(input) ~= 'table' or type(input.name) ~= 'string' then
       return nil, 'invalid input'

    end

   return {
      greeting = "hello " .. input.name
   }
end
```

If the plugin is invoked by POSTing `{"name":"world"}`, then

- `input` is the Lua object `{ name = "world" }`,
- `run` returns the Lua object `{ greeting = "hello world" }`, and
- the plugin replies with 200 OK and the JSON `{"greeting":"hello world"}`.

Plugins may use the Fortanix DSM cryptographic and key management APIs through an object-oriented API similar to the REST API.

For example,

```bash
>function run(input)
   local key = assert(Sobject { name = "Test Key" }) -- Get a key by name
   -- If "Test Key" isn't found, `assert` will throw the error, and the client will see a 500 Internal Server Error.

   local key2 = assert(Sobject { id = 'd1ebab99-c815-422c-9f7d-9ad1b8c5de97' }) -- Get a key by ID

   local key3, err = Sobject { name = input.name } -- Get a key by name, handling errors manually
   if not key then return nil, "Key " .. input.name .. " not found" end -- blame the client if error (400 Bad Request)

   local encrypt_result, err = key:encrypt {
      mode = 'CBC',
      plain = 'aGVsbG8gd29ybGQ=' -- Like the REST API, plugins may pass binary data as a base64-encode string
   }
   if not key then return nil, "Error encrypting with Test Key: " .. tostring(err) end

   -- Plugins may also pass binary data as a `Blob`, which is more powerful
   local plain = Blob.from_bytes('hello world')
   assert(plain:bytes() == 'hello world')
   assert(plain:base64() == 'aGVsbG8gd29ybGQ=')
   assert(plain == Blob.from_base64('aGVsbG8gd29ybGQ='))

   local encrypt_result, err = key:encrypt {
      mode = 'CBC',
      plain = plain,
   }
   if not key then return nil, "Error encrypting with Test Key: " .. tostring(err) end

   return {
      cipher = encrypt_result.cipher, -- Binary data is returned as a `Blob`, which encodes to base64
      iv = encrypt_result.iv,
   }
end
```

A plugin may get information about the entity that invoked it, the “principal”:

```bash
function run(input)
   local principal = principal() -- either `{ app = '' }`, `{ user = '' }`, or `{ plugin = '' }`
   local principal_type = principal:type() -- 'app', 'user', or 'plugin'
   local principal_id = principal:id() -- ''

   local principal_entity = principal:entity() -- the app, user, or plugin object

   return "Plugin was invoked by a " .. principal_type .. " with name " .. principal_entity.name
end
```

## 4.0 How to Configure?

Like Fortanix DSM applications, Fortanix DSM plugins are entities that may belong to multiple groups.

A plugin may use a Security-object if and only if it shares a group with the security object.

An app, user, or another plugin may invoke a plugin if and only if it shares a group with the plugin.

In a typical configuration, a plugin will be in a privileged group A that contains the keys the plugin will use, as well as a less privileged group B that contains the apps that will invoke the plugin.

Since the apps in the less privileged group B aren’t in the privileged group A, the apps may only access the keys by invoking the plugin, which may enforce access control policies, invariants, etc.

Fortanix Data Security Manager (DSM) is the world’s first cloud service secured with Intel® SGX. With Fortanix DSM, you can securely generate, store, and use cryptographic keys and certificates, as well as other secrets such as passwords, API keys, tokens, or any blob of data. Your business-critical applications and containers can integrate with Fortanix DSM using legacy cryptographic interfaces (PKCS#11, CNG, and JCE) or using the native Fortanix DSM RESTful interface.

A security object is any datum stored in DSM (for example a key, a certificate, a password, or other security objects). Each security object is assigned to exactly one group. users and applications assigned to the group have permission to see the security object and to perform operations on it.

## Related

- [Plugin Library](/dsm-plugin-library.md)
- [Plugins – Lua Programming Reference](/fortanix-dsm-plugins-lua-programming-reference.md)
- [SDKs for REST API](/fortanix-dsm-clients-sdks-for-rest-api.md)
