<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE reference PUBLIC "-//OASIS//DTD DocBook V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<reference>
<title>SSSD Manual pages</title>
<refentry>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="include/upstream.xml" />
<refmeta>
<refentrytitle>sssd-secrets</refentrytitle>
<manvolnum>5</manvolnum>
<refmiscinfo class="manual">File Formats and Conventions</refmiscinfo>
</refmeta>
<refnamediv id='name'>
<refname>sssd-secrets</refname>
<refpurpose>SSSD Secrets responder</refpurpose>
</refnamediv>
<refsect1 id='description'>
<title>DESCRIPTION</title>
<para>
This manual page describes the configuration of the Secrets responder
for
<citerefentry>
<refentrytitle>sssd</refentrytitle>
<manvolnum>8</manvolnum>
</citerefentry>.
For a detailed syntax reference, refer to the <quote>FILE FORMAT</quote> section of the
<citerefentry>
<refentrytitle>sssd.conf</refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry> manual page.
</para>
<para>
Many system and user applications need to store private
information such as passwords or service keys and have no good
way to properly deal with them. The simple approach is to embed
these <quote>secrets</quote> into configuration files
potentially ending up exposing sensitive key material to
backups, config management system and in general making it
harder to secure data.
</para>
<para>
The <ulink url="https://github.com/latchset/custodia">custodia</ulink>
project was born to deal with this problem in cloud like
environments, but we found the idea compelling even at a
single system level. As a security service, SSSD is ideal to
host this capability while offering the same API via a UNIX
Socket. This will make it possible to use local calls and have
them transparently routed to a local or a remote key management
store like IPA Vault for storage, escrow and recovery.
</para>
<para>
The secrets are simple key-value pairs. Each user's secrets are
namespaced using their user ID, which means the secrets will never
collide between users. Secrets can be stored inside
<quote>containers</quote> which can be nested.
</para>
<para>
Since the secrets responder can be used both externally to store
general secrets, as described in the rest of this man page, but
also internally by other SSSD components to store their secret
material, some configuration options, like quotas can be configured
per <quote>hive</quote> in a configuration subsection named after
the hive. The currently supported hives are:
<variablelist>
<varlistentry>
<term>secrets</term>
<listitem><para>secrets for general usage</para></listitem>
</varlistentry>
<varlistentry>
<term>kcm</term>
<listitem>
<para>used by the
<citerefentry>
<refentrytitle>sssd-kcm</refentrytitle>
<manvolnum>8</manvolnum>
</citerefentry>
service.
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
</refsect1>
<refsect1 id='usage'>
<title>USING THE SECRETS RESPONDER</title>
<para>
The UNIX socket the SSSD responder listens on is located at
<filename>/var/run/secrets.socket</filename>.
</para>
<para>
The secrets responder is socket-activated by
<citerefentry>
<refentrytitle>systemd</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry>.
Unlike
other SSSD responders, it cannot be started by adding the
<quote>secrets</quote> string to the <quote>service</quote>
directive.
The systemd socket unit is called
<quote>sssd-secrets.socket</quote> and the corresponding service
file is called <quote>sssd-secrets.service</quote>. In order
for the service to be socket-activated, make sure the socket
is enabled and active and the service is enabled:
<programlisting>
systemctl start sssd-secrets.socket
systemctl enable sssd-secrets.socket
systemctl enable sssd-secrets.service
</programlisting>
Please note your distribution may already configure the units
for you.
</para>
</refsect1>
<refsect1 id='options'>
<title>CONFIGURATION OPTIONS</title>
<para>
The generic SSSD responder options such as
<quote>debug_level</quote> or <quote>fd_limit</quote> are
accepted by the secrets responder. Please refer to the
<citerefentry>
<refentrytitle>sssd.conf</refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry> manual page for a complete list. In addition,
there are some secrets-specific options as well.
</para>
<para>
The secrets responder is configured with a global
<quote>[secrets]</quote> section and an optional per-user
<quote>[secrets/users/$uid]</quote> section in
<filename>sssd.conf</filename>. Please note that some options,
notably as the provider type, can only be specified in the per-user
subsections.
</para>
<variablelist>
<varlistentry>
<term>provider (string)</term>
<listitem>
<para>
This option specifies where should the secrets be
stored. The secrets responder can configure a per-user
subsections (e.g. <quote>[secrets/users/123]</quote>
- see bottom of this manual page for a full example
using Custodia for a particular user) that define
which provider store the secrets for this particular
user. The per-user subsections should contain all
options for that user's provider. Please note that
currently the global provider is always local, the
proxy provider can only be specified in a per-user
section. The following providers are supported:
<variablelist>
<varlistentry>
<term>local</term>
<listitem>
<para>
The secrets are stored in a local database,
encrypted at rest with a master key. The local
provider does not have any additional config options
at the moment.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>proxy</term>
<listitem>
<para>
The secrets responder forwards the requests to
a Custodia server. The proxy provider supports
several additional options (see below).
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
<para>
Default: local
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
The following options affect only the secrets <quote>hive</quote>
and therefore should be set in a per-hive subsection. Setting the
option to 0 means "unlimited".
</para>
<variablelist>
<varlistentry>
<term>containers_nest_level (integer)</term>
<listitem>
<para>
This option specifies the maximum allowed number of nested
containers.
</para>
<para>
Default: 4
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>max_secrets (integer)</term>
<listitem>
<para>
This option specifies the maximum number of secrets that
can be stored in the hive.
</para>
<para>
Default: 1024 (secrets hive), 256 (kcm hive)
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>max_uid_secrets (integer)</term>
<listitem>
<para>
This option specifies the maximum number of secrets that
can be stored per-UID in the hive.
</para>
<para>
Default: 256 (secrets hive), 64 (kcm hive)
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>max_payload_size (integer)</term>
<listitem>
<para>
This option specifies the maximum payload size allowed for
a secret payload in kilobytes.
</para>
<para>
Default: 16 (secrets hive), 65536 (64 MiB) (kcm hive)
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
For example, to adjust quotas differently for both the <quote>secrets</quote>
and the <quote>kcm</quote> hives, configure the following:
<programlisting>
[secrets/secrets]
max_payload_size = 128
[secrets/kcm]
max_payload_size = 256
</programlisting>
</para>
<para>
The following options are only applicable for configurations that
use the <quote>proxy</quote> provider.
</para>
<variablelist>
<varlistentry>
<term>proxy_url (string)</term>
<listitem>
<para>
The URL the Custodia server is listening on. At the moment,
http and https protocols are supported.
</para>
<para>
The format of the URI must match the format defined in RFC 2732:
</para>
<para>
http[s]://&lt;host&gt;[:port]
</para>
<para>
Example: http://localhost:8080
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>auth_type (string)</term>
<listitem>
<para>
The method to use when authenticating to a Custodia server. The
following authentication methods are supported:
</para>
<variablelist>
<varlistentry>
<term>basic_auth</term>
<listitem>
<para>
Authenticate with a username and a password as set
in the <quote>username</quote> and
<quote>password</quote> options.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>header</term>
<listitem>
<para>
Authenticate with HTTP header value as defined in
the <quote>auth_header_name</quote> and
<quote>auth_header_value</quote>
configuration options.
</para>
</listitem>
</varlistentry>
</variablelist>
</listitem>
</varlistentry>
<varlistentry>
<term>auth_header_name (string)</term>
<listitem>
<para>
If set, the secrets responder would put a header with this name
into the HTTP request with the value defined in the
<quote>auth_header_value</quote> configuration option.
</para>
<para>
Example: MYSECRETNAME
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>auth_header_value (string)</term>
<listitem>
<para>
The value sssd-secrets would use for the
<quote>auth_header_name</quote>.
</para>
<para>
Example: mysecret
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>forward_headers (list of strings)</term>
<listitem>
<para>
The list of HTTP headers to forward to the Custodia server
together with the request.
</para>
<para>
Default: not set
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>verify_peer (boolean)</term>
<listitem>
<para>
Whether peer's certificate should be verified and valid
if HTTPS protocol is used with the proxy provider.
</para>
<para>
Default: true
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>verify_host (boolean)</term>
<listitem>
<para>
Whether peer's hostname must match with hostname in
its certificate if HTTPS protocol is used with the
proxy provider.
</para>
<para>
Default: true
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>capath (string)</term>
<listitem>
<para>
Path to directory containing stored certificate authority
certificates. System default path is used if this option is
not set.
</para>
<para>
Default: not set
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>cacert (string)</term>
<listitem>
<para>
Path to file containing server's certificate authority
certificate. If this option is not set then the CA's
certificate is looked up in <quote>capath</quote>.
</para>
<para>
Default: not set
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>cert (string)</term>
<listitem>
<para>
Path to file containing client's certificate if required
by the server. This file may also contain private key or
the private key may be in separate file set with
<quote>key</quote>.
</para>
<para>
Default: not set
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>key (string)</term>
<listitem>
<para>
Path to file containing client's private key.
</para>
<para>
Default: not set
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 id='restapi'>
<title>USING THE REST API</title>
<para>
This section lists the available commands and includes examples using the
<citerefentry>
<refentrytitle>curl</refentrytitle>
<manvolnum>1</manvolnum>
</citerefentry> utility.
All requests towards the proxy provider must set the Content
Type header to <quote>application/json</quote>. In addition,
the local provider also supports Content Type set to
<quote>application/octet-stream</quote>.
Secrets stored with requests that set the Content Type header
to <quote>application/octet-stream</quote> are base64-encoded
when stored and decoded when retrieved, so it's not possible to
store a secret with one Content Type and retrieve with another.
The secret URI must begin with <filename>/secrets/</filename>.
</para>
<variablelist>
<varlistentry>
<term>Listing secrets</term>
<listitem>
<para>
To list the available secrets, send a HTTP GET request
with a trailing slash appended to the container path.
</para>
<para>
Example:
<programlisting>
curl -H "Content-Type: application/json" \
--unix-socket /var/run/secrets.socket \
-XGET http://localhost/secrets/
</programlisting>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Retrieving a secret</term>
<listitem>
<para>
To read a value of a single secret, send a HTTP GET request
without a trailing slash. The last portion of the URI is the name
of the secret.
</para>
<para>
Examples:
<programlisting>
curl -H "Content-Type: application/json" \
--unix-socket /var/run/secrets.socket \
-XGET http://localhost/secrets/foo
</programlisting>
<programlisting>
curl -H "Content-Type: application/octet-stream" \
--unix-socket /var/run/secrets.socket \
-XGET http://localhost/secrets/bar
</programlisting>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Setting a secret</term>
<listitem>
<para>
To set a secret using the <quote>application/json</quote>
type, send a HTTP PUT request with a
JSON payload that includes type and value. The type
should be set to "simple" and the value should be
set to the secret value. If a secret with that name
already exists, the response is a 409 HTTP error.
</para>
<para>
The <quote>application/json</quote> type just sends
the secret as the message payload.
</para>
<para>
The following example sets a secret named 'foo'
to a value of 'foosecret' and a secret named 'bar'
to a value of 'barsecret' using a different
Content Type.
<programlisting>
curl -H "Content-Type: application/json" \
--unix-socket /var/run/secrets.socket \
-XPUT http://localhost/secrets/foo \
-d'{"type":"simple","value":"foosecret"}'
</programlisting>
<programlisting>
curl -H "Content-Type: application/octet-stream" \
--unix-socket /var/run/secrets.socket \
-XPUT http://localhost/secrets/bar \
-d'barsecret'
</programlisting>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Creating a container</term>
<listitem>
<para>
Containers provide an additional namespace for
this user's secrets. To create a container, send
a HTTP POST request, whose URI ends with the
container name. Please note the URI must end with
a trailing slash.
</para>
<para>
The following example creates a container named
'mycontainer':
<programlisting>
curl -H "Content-Type: application/json" \
--unix-socket /var/run/secrets.socket \
-XPOST http://localhost/secrets/mycontainer/
</programlisting>
</para>
<para>
To manipulate secrets under this container, just nest the
secrets underneath the container path:
<programlisting>
http://localhost/secrets/mycontainer/mysecret
</programlisting>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Deleting a secret or a container</term>
<listitem>
<para>
To delete a secret or a container, send a HTTP DELETE
request with a path to the secret or the container.
</para>
<para>
The following example deletes a secret named 'foo'.
<programlisting>
curl -H "Content-Type: application/json" \
--unix-socket /var/run/secrets.socket \
-XDELETE http://localhost/secrets/foo
</programlisting>
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1 id='custodia_example'>
<title>EXAMPLE CUSTODIA AND PROXY PROVIDER CONFIGURATION</title>
<para>
For testing the proxy provider, you need to set up a Custodia server
to proxy requests to. Please always consult the Custodia documentation,
the configuration directives might change with different Custodia versions.
</para>
<para>
This configuration will set up a Custodia server listening on
http://localhost:8080, allowing anyone with header named MYSECRETNAME
set to mysecretkey to communicate with the Custodia server.
Place the contents into a file (for example,
<replaceable>custodia.conf</replaceable>):
<programlisting>
[global]
server_version = "Secret/0.0.7"
server_url = http://localhost:8080/
auditlog = /var/log/custodia.log
debug = True
[store:simple]
handler = custodia.store.sqlite.SqliteStore
dburi = /var/lib/custodia.db
table = secrets
[auth:header]
handler = custodia.httpd.authenticators.SimpleHeaderAuth
header = MYSECRETNAME
value = mysecretkey
[authz:paths]
handler = custodia.httpd.authorizers.SimplePathAuthz
paths = /secrets
[/]
handler = custodia.root.Root
store = simple
</programlisting>
</para>
<para>
Then run the <replaceable>custodia</replaceable> command, pointing it
at the config file as a command line argument.
</para>
<para>
Please note that currently it's not possible to proxy all
requests globally to a Custodia instance. Instead, per-user
subsections for user IDs that should proxy requests to Custodia
must be defined. The following example illustrates a configuration,
where the user with UID 123 would proxy their requests to Custodia,
but all other user's requests would be handled by a local provider.
</para>
<programlisting>
[secrets]
[secrets/users/123]
provider = proxy
proxy_url = http://localhost:8080/secrets/
auth_type = header
auth_header_name = MYSECRETNAME
auth_header_value = mysecretkey
</programlisting>
</refsect1>
</refentry>
</reference>