From 1274da27c40e5acf9a0d09e176309c68f2515309 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Mon, 8 Aug 2016 17:48:51 +0200
Subject: [PATCH] MAN: sssd-secrets documentation

Resolves:
    https://fedorahosted.org/sssd/ticket/3053

Documents the API and the purpose of the sssd-secrets responder.
---
 contrib/sssd.spec.in                     |   1 +
 src/man/Makefile.am                      |   9 +-
 src/man/po/po4a.cfg                      |   1 +
 src/man/sssd-secrets.5.xml               | 437 +++++++++++++++++++++++++++++++
 src/sysv/systemd/sssd-secrets.service.in |   1 +
 src/sysv/systemd/sssd-secrets.socket.in  |   1 +
 6 files changed, 449 insertions(+), 1 deletion(-)
 create mode 100644 src/man/sssd-secrets.5.xml

diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in
index 1f79ca7..a4daaf9 100644
--- a/contrib/sssd.spec.in
+++ b/contrib/sssd.spec.in
@@ -818,6 +818,7 @@ done
 %{_mandir}/man5/sssd.conf.5*
 %{_mandir}/man5/sssd-simple.5*
 %{_mandir}/man5/sssd-sudo.5*
+%{_mandir}/man5/sssd-secrets.5*
 %{_mandir}/man5/sss_rpcidmapd.5*
 %{_mandir}/man8/sssd.8*
 %{_mandir}/man8/sss_cache.8*
diff --git a/src/man/Makefile.am b/src/man/Makefile.am
index cd23b02..5e41d3a 100644
--- a/src/man/Makefile.am
+++ b/src/man/Makefile.am
@@ -24,12 +24,15 @@ endif
 if BUILD_IFP
 IFP_CONDS = ;with_ifp
 endif
+if BUILD_SECRETS
+SEC_CONDS = ;with_secrets
+endif
 if GPO_DEFAULT_ENFORCING
 GPO_CONDS = ;gpo_default_enforcing
 else
 GPO_CONDS = ;gpo_default_permissive
 endif
-CONDS = with_false$(SUDO_CONDS)$(AUTOFS_CONDS)$(SSH_CONDS)$(PAC_RESPONDER_CONDS)$(IFP_CONDS)$(GPO_CONDS)
+CONDS = with_false$(SUDO_CONDS)$(AUTOFS_CONDS)$(SSH_CONDS)$(PAC_RESPONDER_CONDS)$(IFP_CONDS)$(GPO_CONDS)$(SEC_CONDS)
 
 
 #Special Rules:
@@ -70,6 +73,10 @@ if BUILD_IFP
 man_MANS += sssd-ifp.5
 endif
 
+if BUILD_SECRETS
+man_MANS += sssd-secrets.5
+endif
+
 if BUILD_NFS_IDMAP
 man_MANS += sss_rpcidmapd.5
 endif
diff --git a/src/man/po/po4a.cfg b/src/man/po/po4a.cfg
index 2a51731..a673556 100644
--- a/src/man/po/po4a.cfg
+++ b/src/man/po/po4a.cfg
@@ -28,6 +28,7 @@
 [type:docbook] sss_ssh_knownhostsproxy.1.xml $lang:$(builddir)/$lang/sss_ssh_knownhostsproxy.1.xml
 [type:docbook] idmap_sss.8.xml $lang:$(builddir)/$lang/idmap_sss.8.xml
 [type:docbook] sssctl.8.xml $lang:$(builddir)/$lang/sssctl.8.xml
+[type:docbook] sssd-secrets.5.xml $lang:$(builddir)/$lang/sssd-secrets.5.xml
 [type:docbook] include/service_discovery.xml $lang:$(builddir)/$lang/include/service_discovery.xml opt:"-k 0"
 [type:docbook] include/upstream.xml $lang:$(builddir)/$lang/include/upstream.xml opt:"-k 0"
 [type:docbook] include/failover.xml $lang:$(builddir)/$lang/include/failover.xml opt:"-k 0"
diff --git a/src/man/sssd-secrets.5.xml b/src/man/sssd-secrets.5.xml
new file mode 100644
index 0000000..18b355e
--- /dev/null
+++ b/src/man/sssd-secrets.5.xml
@@ -0,0 +1,437 @@
+<?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 secrets
+             such as passwords or service keys and have no good way to
+             properly deal with them. The simple approach is to embed
+             these secrets 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>
+    </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 systemd and cannot be
+            started by adding the <quote>secrets</quote> string to the
+            <quote>services</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>
+        <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 that define which provider store
+                    the secrets for this particular user. The per-user
+                    subsections should contain all options for that user's
+                    provider. If a per-user section does not exist, the
+                    global settings from the secret responder's section
+                    are used.  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 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>
+        </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>
diff --git a/src/sysv/systemd/sssd-secrets.service.in b/src/sysv/systemd/sssd-secrets.service.in
index 119c9bb..f45d647 100644
--- a/src/sysv/systemd/sssd-secrets.service.in
+++ b/src/sysv/systemd/sssd-secrets.service.in
@@ -1,5 +1,6 @@
 [Unit]
 Description=SSSD Secrets Service responder
+Documentation=man:sssd-secrets(5)
 
 [Install]
 Also=sssd-secrets.socket
diff --git a/src/sysv/systemd/sssd-secrets.socket.in b/src/sysv/systemd/sssd-secrets.socket.in
index 682e8f6..fb64852 100644
--- a/src/sysv/systemd/sssd-secrets.socket.in
+++ b/src/sysv/systemd/sssd-secrets.socket.in
@@ -1,5 +1,6 @@
 [Unit]
 Description=SSSD Secrets Service responder socket
+Documentation=man:sssd-secrets(5)
 
 [Socket]
 ListenStream=@localstatedir@/run/secrets.socket
