<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0"><channel><title>Barbican Specs</title><link>https://specs.openstack.org/openstack/barbican-specs</link><description /><language>en</language><copyright>2024, OpenStack Barbican Team</copyright><item><title>Secret Consumers</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/train/secret-consumers.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://storyboard.openstack.org/#!/story/2005770"&gt;https://storyboard.openstack.org/#!/story/2005770&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This spec proposes an addition to the Barbican Secrets API to allow
other OpenStack projects to add references to individual Secrets when
those secrets are being used by them.&lt;/p&gt;
&lt;p&gt;This spec also proposes a change to both the Python and CLI clients in
python-barbicanclient in how they handle the deletion of secrets.
Clients would be changed such that deleting a secret will result in an
error when they are still being consumed by another project unless a &lt;cite&gt;force&lt;/cite&gt;
parameter is provided.&lt;/p&gt;
&lt;p&gt;This spec is part of a larger effort to provide Encrypted Images
to OpenStack clouds.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Other OpenStack projects would like to make use of an end user’s secrets
e.g. A Secret that contains an encryption key for Image Encryption.
But there is currently no way for those projects to let the user know
that they are using the Secret.  This lack of awareness may lead to errors
if the user deletes a Secret that is still in use by other projects.&lt;/p&gt;
&lt;p&gt;On the other hand, users should be allowed to delete secrets whenever they
want, so a Secret being used by other projects should not prevent deletion.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Add a new API to Secrets to register Secret Consumers (similar, but not
identical to the Containers Consumer API [1]).&lt;/p&gt;
&lt;p&gt;With this new API, other OpenStack projects would register as a consumer
of a secret by sending a request to Barbican.  Barbican stores the service
type of the requesting service, as well as both the resource type and
resource ID of the resource that is using the Secret.&lt;/p&gt;
&lt;p&gt;See REST API Impact below for details of the API changes.&lt;/p&gt;
&lt;p&gt;Clients to barbican would change the semantics for deleting secrets by
returning an error when trying to delete a secret if that secret has one
or more consumers.  Clients will also accept an additional boolean parameter
to delete a secret regardless of how many consumers it has.&lt;/p&gt;
&lt;p&gt;See Python and Command Line Client Impact below for details of the client
changes.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;One alternative would be to implement Secret Consumers just like Container
Consumers, which uses a URL instead of the consuming entity type and ID.&lt;/p&gt;
&lt;p&gt;Another alternative approach that was considered was to have each project
clone the secret when they need to use it.  This alternative has some
downsides, however.  For one, an end user may not be able to delete
those copies.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;A new model and associated data table will need to be added. For example,
a new class SecretConsumerMetadatum with a secret_consumer_metadata table.&lt;/p&gt;
&lt;p&gt;The new class will have references to both the secret_id as well as the
project_id which owns the secret.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;section id="post-v1-secrets-secret-id-consumers"&gt;
&lt;h4&gt;POST /v1/secrets/{secret_id}/consumers&lt;/h4&gt;
&lt;p&gt;Add a new resource as a consumer to a secret.&lt;/p&gt;
&lt;section id="body-parameters"&gt;
&lt;h5&gt;Body Parameters&lt;/h5&gt;
&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;service&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Consumer’s OpenStack service type as shown in
&lt;a class="reference external" href="https://service-types.openstack.org/service-types.json"&gt;https://service-types.openstack.org/service-types.json&lt;/a&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;resource_type
(or resource_path?)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Name of the resource type using the secret
e.g. “images”  or “lbaas/loadbalancers”&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;resource_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unique identifier for the resource using this secret.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Barbican will consider the resource_id to be a unique together with the secret,
service and resource_type. If the resource_id is a UUID, duplicate IDs for
different projects are not likely to ever happen in a single cloud.&lt;/p&gt;
&lt;p&gt;resource_type should be meaningful to the individual projects, and should
be used to identify the resource in the consuming service.  For example,
Glance could use “images” as the value of the resource type to indicate that
the resrouce_id refers to an image.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="request"&gt;
&lt;h5&gt;Request&lt;/h5&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;secret_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;consumers&lt;/span&gt;
&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"service"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"image"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"resource_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"images"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"resource_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{image_id}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="responses"&gt;
&lt;h5&gt;Responses&lt;/h5&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Code&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;200&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;OK&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;401&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized - X-Auth-Token is invalid&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;403&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;Forbidden - X-Auth-Token is valid, but the associated project does&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;not have the appropriate role/scope&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="get-v1-secrets-secret-id-consumers"&gt;
&lt;h4&gt;GET /v1/secrets/{secret_id}/consumers&lt;/h4&gt;
&lt;p&gt;List consumers for a particular Secret.&lt;/p&gt;
&lt;section id="parameters"&gt;
&lt;h5&gt;Parameters&lt;/h5&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;offset&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;0&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Offset to start consumer response&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;limit&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;integer&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;10&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Number of consumer entries returned in response&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;service&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;None&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Filter by service type&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id="id1"&gt;
&lt;h5&gt;Request&lt;/h5&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;secret_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;consumers&lt;/span&gt;
&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="ok-response"&gt;
&lt;h5&gt;OK Response&lt;/h5&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"total"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"consumers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"service"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"image"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"resource_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"images"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"resource_id"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{image_id}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="other-responses"&gt;
&lt;h5&gt;Other Responses&lt;/h5&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Code&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;401&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized - X-Auth-Token is invalid&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;403&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;Forbidden - X-Auth-Token is valid, but the associated project does&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;not have the appropriate role/scope&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="delete-v1-secrets-secret-id-consumers"&gt;
&lt;h4&gt;DELETE /v1/secrets/{secret_id}/consumers&lt;/h4&gt;
&lt;p&gt;Delete a consumer.  ie. The resource is being deleted and it longer needs
to access this secret.&lt;/p&gt;
&lt;section id="id2"&gt;
&lt;h5&gt;Request&lt;/h5&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;DELETE&lt;/span&gt; &lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;secret_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;consumers&lt;/span&gt;
&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"service"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"image"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"resource_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"images"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"resource_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{image_id}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="id3"&gt;
&lt;h5&gt;Responses&lt;/h5&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Code&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;200&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;OK&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;401&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Unauthorized - X-Auth-Token is invalid&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;403&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;Forbidden - X-Auth-Token is valid, but the associated project does&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;not have the appropriate role/scope&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;404&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Not Found - Consumer record for given resource_id was not found.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;Because the consumers are stored in the database, there is the possibility
that a bad actor could add many consumers to try to fill the database disk
space.  Secret Consumers should be limited to the same quota as Container
Consumers to mitigate this risk. For example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;quota&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;quota_consumers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10000&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Would limit both Container Consumers and Secret Consumers to a maximum
of 10,000 consumers each for both a single Container or a single Secret.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h3&gt;Notifications &amp;amp; Audit Impact&lt;/h3&gt;
&lt;p&gt;The new API endpoints should be audited as usual.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="python-and-command-line-client-impact"&gt;
&lt;h3&gt;Python and Command Line Client Impact&lt;/h3&gt;
&lt;p&gt;The Secret class in python-barbicanclient should be updated to add new
methods such as:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SecretManager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;register_consumer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;secret_ref&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;service_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resource_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resource_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="o"&gt;...&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;remove_consumer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;secret_ref&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;service_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resource_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resource_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Both methods should raise appropriate exceptions when the API returns an error.
Additionally, the SecretManager.delete() method should be updated to take a new
&lt;em&gt;force&lt;/em&gt; parameter and throw an exception when delete() is called with
force=False and the secret still has consumers:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SecretManager&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;container_ref&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;force&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The CLI client should be changed to add new consumer options, such as:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;secret&lt;/span&gt; &lt;span class="n"&gt;consumer&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt; \
    &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;XXXX&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;XXXX&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;XXXX&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;XXXX&lt;/span&gt;

&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;secret&lt;/span&gt; &lt;span class="n"&gt;consumer&lt;/span&gt; &lt;span class="n"&gt;remove&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt; \
    &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;XXXX&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;XXXX&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;XXXX&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;XXXX&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The secret delete command should be changed to take a &lt;em&gt;–force&lt;/em&gt; parameter:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;secret&lt;/span&gt; &lt;span class="n"&gt;delete&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;force&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;secret_uuid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This command should return an error when a secret has one or more consumers
and the –force flag is not used:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;openstack&lt;/span&gt; &lt;span class="n"&gt;secret&lt;/span&gt; &lt;span class="n"&gt;delete&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;secret_uuid_with_consumers&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;ERROR&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Secret&lt;/span&gt; &lt;span class="n"&gt;has&lt;/span&gt; &lt;span class="n"&gt;one&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;more&lt;/span&gt; &lt;span class="n"&gt;consumers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;  &lt;span class="n"&gt;Use&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;force&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;delete&lt;/span&gt; &lt;span class="n"&gt;anyway&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;These changes will require a new Major version for python-barbicanclient
because the default –force=False option could cause some scripts to break in
certain scenarios where secrets are currently being deleted that do have
consumers associated with them.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;Currently there is no other impact to the end user other than the CLI changes
listed above.  In the future, when a barbican-ui for Horizon is developed,
it should use the consumers to present confirmation dialogs to the user
when deleting Secrets which have consumers.&lt;/p&gt;
&lt;p&gt;It should be noted that Deleting Secrets in the Barbican REST API
has not changed, and a client using the API directly will be able to delete
a secret regardless of the presence of consumers.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Deleting secrets using the CLI or the Python client will be affected as we
will likely need to perform additional requests to the API to get the list of
consumers for a secret before sending a DELETE request.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;When python-barbican changes are merged, some automation scripts that use
secret deletion may break if the secrets being deleted have consumers.&lt;/p&gt;
&lt;p&gt;Any automation scripts should be updated to use the –force flag if needed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Developers of other projects that want to make use of this feature will
need to use python-barbicanclient to integrate with the Key Manager service.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;Assignee(s)&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Douglas Mendizábal (OFTC: redrobot) &amp;lt;&lt;a class="reference external" href="mailto:dmendiza%40redhat.com"&gt;dmendiza&lt;span&gt;@&lt;/span&gt;redhat&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Moisés Guimarães (OFTC: moguimar) &amp;lt;&lt;a class="reference external" href="mailto:moguimar%40redhat.com"&gt;moguimar&lt;span&gt;@&lt;/span&gt;redhat&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;
Grzegorz Grasza (OFTC: xek) &amp;lt;&lt;a class="reference external" href="mailto:xek%40redhat.com"&gt;xek&lt;span&gt;@&lt;/span&gt;redhat&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement Model changes and database migration&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement API changes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement python-barbicanclient changes (both python client and CLI)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Tempest test cases should be added to test adding/removing Secret Consumers
using a service-user that is not barbican.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;All API changes should be documented in the API reference, as well as the
API Guide.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] Container Consumers API:
&lt;a class="reference external" href="https://docs.openstack.org/barbican/stein/api/reference/consumers.html"&gt;https://docs.openstack.org/barbican/stein/api/reference/consumers.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Barbican Train PTG Etherpad:
&lt;a class="reference external" href="https://etherpad.openstack.org/p/barbican-train-ptg"&gt;https://etherpad.openstack.org/p/barbican-train-ptg&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Fri, 09 Sep 2022 00:00:00 </pubDate></item><item><title>Add Support For Mutable Generic Containers Resource</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/newton/api-containers-add-put.html</link><description>

&lt;p&gt;The URL of the associated launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/api-containers-add-put"&gt;https://blueprints.launchpad.net/barbican/+spec/api-containers-add-put&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The original intent of the ‘generic’ container type was to support arbitrary
secrets to be collected and referenced, similar to a file system folder. Hence
it makes sense for an already-created ‘generic’ container to support changing
this collection after the fact. This blueprint details how this API would look.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Currently Barbican allows a ‘generic’-typed container to be created via a POST
call, but once that container is created it is not possible to modify it to
change which secrets it contains. The ‘generic’ container was intended to be a
convenient way to collect related secrets and as such should allow for
modification after it is created.&lt;/p&gt;
&lt;p&gt;For example continuous integration and deployment systems might wish to collect
all secrets for a given environment such as database passwords and access
tokens, for use by automation scripts when servers are created in the
environment later. It would be convenient if each environment could have its
own Barbican container that automation scripts could reference to retrieve
secrets (by their fixed key names) as part of booting up servers in that
environment. If secrets are later rotated or updated, the secret references
for a given key name could be updated in the container, with no need to update
the automation scripts.&lt;/p&gt;
&lt;p&gt;Attempts to update containers of other types will be rejected.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;This blueprint calls for adding new sub-resources to generic containers.
The API impact section details what these calls look like relative to clients.
The actual service implementation is straightforward though, allowing clients
to provide additional secrets or delete individual secrets by sending a POST or
DELETE request to the sub-resources in a ‘generic’ container.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;A previously-accepted but not implemented version of this blueprint called
for adding PUT support for containers whereby clients must specify all secrets
to be held in the container. For example when adding a secret to an existing
container the PUT body would have to list all existing secrets in addition to
the new secret. However, during the Newton cycle we discussed that this could
be error-prone due to potential race conditions.&lt;/p&gt;
&lt;p&gt;Utilize a PATCH call to provide partial updates to containers. This adds
complexity to API processing, especially if JSONPatch [1] is used. If this
feature is deemed necessary, that should be proposed as a separate blueprint.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;The following documentation specifies the proposed container sub-resource
calls, used to add or remove a secret from  an existing ‘generic’-type
container.&lt;/p&gt;
&lt;p&gt;The access policy for this call is similar to the container resource’s POST
call, so users with the Barbican ‘admin’ or ‘creator’ role can modify
containers.&lt;/p&gt;
&lt;section id="post-v1-containers-container-uuid-secrets"&gt;
&lt;h4&gt;POST /v1/containers/{container_uuid}/secrets&lt;/h4&gt;
&lt;p&gt;Add a secret to an existing container.  This is only supported on generic
containers.&lt;/p&gt;
&lt;section id="request-attributes"&gt;
&lt;h5&gt;Request Attributes&lt;/h5&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;string&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;(optional) Human readable name for identifying your secret
within the container.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;secret_ref&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;uri&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;(required) Full URI reference to an existing secret.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id="request"&gt;
&lt;h5&gt;Request:&lt;/h5&gt;
&lt;div class="highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;POST /v1/containers/{container_uuid}/secrets
Headers:
    X-Project-Id: {project_id}

Content:
{
    "name": "private_key",
    "secret_ref": "https://{barbican_host}/v1/secrets/{secret_uuid}"
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="response"&gt;
&lt;h5&gt;Response:&lt;/h5&gt;
&lt;div class="highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;{
    "container_ref": "https://{barbican_host}/v1/containers/{container_uuid}"
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note that the requesting ‘container_uuid’ is the same as that provided in the
response.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="http-status-codes"&gt;
&lt;h5&gt;HTTP Status Codes&lt;/h5&gt;
&lt;p&gt;In general, error codes produced by the containers POST call pertain here as
well, especially in regards to the secret references that can be provided.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Code&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;201&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Successful update of the container&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;400&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Missing secret_ref&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;401&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Invalid X-Auth-Token or the token doesn’t have permissions to this resource&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="delete-v1-containers-container-uuid-secrets"&gt;
&lt;h4&gt;DELETE /v1/containers/{container_uuid}/secrets&lt;/h4&gt;
&lt;p&gt;Remove a secret from a container.  This is only supported on generic
containers.&lt;/p&gt;
&lt;section id="id1"&gt;
&lt;h5&gt;Request:&lt;/h5&gt;
&lt;div class="highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;DELETE /v1/containers/{container_uuid}/secrets
Headers:
    X-Project-Id: {project_id}

Content:
{
    "name": "private key",
    "secret_ref": "https://{barbican_host}/v1/secrets/{secret_uuid}"
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="id2"&gt;
&lt;h5&gt;Response:&lt;/h5&gt;
&lt;div class="highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;204 No Content
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="id3"&gt;
&lt;h5&gt;HTTP Status Codes&lt;/h5&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Code&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;204&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Successful removal of the secret from the container.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;400&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Missing secret_ref&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;401&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Invalid X-Auth-Token or the token doesn’t have permissions to this resource&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;404&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Specified secret_ref is not found in the container.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id="alternative"&gt;
&lt;h5&gt;Alternative&lt;/h5&gt;
&lt;p&gt;Alternatively, we could define the removal of a secret as a call to a resource
that includes the secret_uuid as part of the URI, for example:&lt;/p&gt;
&lt;div class="highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;DELETE /v1/containers/{container_uuid}/secrets/{secret_uuid}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;However, this would require the client to parse out UUIDs from secret URIs to
be able to construct the correct URI for deletion.  Because of this reason
the DELETE with a body described above should be implemented instead.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;The proposed change does not pose a security impact because (1) it does not
alter underlying secrets or their access restrictions, and (2) only ‘generic’-
type containers can be modified hence sensitive grouped secrets such as
‘certificate’- and ‘asymmetric’-type containers remain immutable. Please also
see the Performance Impact section for advice on rate limiting calls such as
the one proposed in this blueprint to avoid denial of service attacks.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h3&gt;Notifications &amp;amp; Audit Impact&lt;/h3&gt;
&lt;p&gt;The proposed new POST and DELETE container request should be logged and audited
the same as any other REST call to Barbican, and therefore does not need to be
called out specifically in this blueprint.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;The Barbican Python client needs to be modified as well.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;As no cryptographic operations are needed for this blueprint, with only
database references to secrets changed, the proposal should have minimal
impact on performance. However, the call itself is not quota limited, so
deployers might wish to utilize a rate limiting application in front of their
Barbican API nodes, such as Repose [2].&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;No configuration or dependency changes are required to utilize the proposed
operation, but as mentioned in the Performance Impact section above if rate
limiting is deployed, the PUT operation on the containers resource should be
limited as well to avoid denial of service attacks.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;TBD&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;TBD&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;The following work items are required to implement this blueprint:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Update container controllers to add the new POST and DELETE sub-resources.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a new policy entry to &lt;cite&gt;etc/policy.json&lt;/cite&gt; for the new operations&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a positive test to modify a ‘generic’-type container, and a negative
test prove that a non-‘generic’-type container cannot be modified.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add Barbican Python client support for the new feature.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add sphinx documentation for the new POST and DELETE actions.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;See the Work Items section above for details on what to test. No special 3rd
party systems are required to test the proposed functionality.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;See the Work Items section above for details on what to document.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] &lt;a class="reference external" href="http://jsonpatch.com/"&gt;http://jsonpatch.com/&lt;/a&gt;
[2] &lt;a class="reference external" href="http://openrepose.org/"&gt;http://openrepose.org/&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 09 Apr 2020 00:00:00 </pubDate></item><item><title>Date Filters</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/newton/date-filters.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/date-filters"&gt;https://blueprints.launchpad.net/barbican/+spec/date-filters&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;In an effort to keep track of the changes being made to secrets or upcoming
expiration dates, users such as IT Auditors or Operations Engineers need to be
able to filter queries sent to the API based on the timestamped properties of a
secret.  These users require new filters to be able to query information about
their secrets such as:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Secrets expiring in the near future&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Secrets created in a particular time range&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Secrets updated in a particular time range&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Currently, Barbican does not provide any filters for querying secrets by
using the properties that hold timestamp values. So a user currently needs
to iterate through their entire secret collection to be able to gather this
data.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The barbican /secrets resource should be enhanced to allow sorting and
filtering based on a secret’s &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;created&lt;/span&gt;&lt;/code&gt;, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;updated&lt;/span&gt;&lt;/code&gt;, and &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;expiration&lt;/span&gt;&lt;/code&gt;
properties as described in the API Working Group’s guideline for &lt;a class="reference external" href="https://git.openstack.org/cgit/openstack/api-wg/tree/guidelines/pagination_filter_sort.rst"&gt;Pagination,
Filtering, and Sorting&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The filters should allow limiting of returned values to specific times and
time ranges by using the equality (&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;=&lt;/span&gt;&lt;/code&gt;), greater-than (&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gt&lt;/span&gt;&lt;/code&gt;),
greater-than-or-equal (&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;gte&lt;/span&gt;&lt;/code&gt;), less-than (&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;lt&lt;/span&gt;&lt;/code&gt;), and
less-than-or-equal (&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;lte&lt;/span&gt;&lt;/code&gt;) operators.&lt;/p&gt;
&lt;p&gt;The filters should also allow the ordering of return values by using the
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;sort&lt;/span&gt;&lt;/code&gt; query string parameter with both ascending (&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;asc&lt;/span&gt;&lt;/code&gt;) and descending
(&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;desc&lt;/span&gt;&lt;/code&gt;) directions for the specified sort key.&lt;/p&gt;
&lt;p&gt;Values passed in to these query parameters are assumed to be give in UTC time
using the extended format described in ISO 8601.  The UTC zone designation
represented by appending the “Z” character will be required.  Values that do
not include the zone designation will result in an error response with status
code 400. Values that specify a time offset from UTC will also result in a 400
error response even if the offset is zero to specify UTC.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Requiring the zone designation for UTC (“Z”) may be too stringent of a
requirement.  One alternative would be to accept time values without the “Z”
zone designation and just assume that the values are all UTC.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;This change will not affect the data model, since all values to be used in the
filtering are already part of the data model.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Additional query parameters will be available for the GET /v1/secrets resource
as described above.&lt;/p&gt;
&lt;p&gt;Examples:&lt;/p&gt;
&lt;p&gt;List secrets expiring in the next week (assuming current time is June 8, 2016
20:00 UTC) and sort by secrets expiring soonest:&lt;/p&gt;
&lt;div class="highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;GET /v1/secrets?expiration=gt:2016-06-08T20:00:00Z,lt:2016-06-15T20:00:00Z&amp;amp;sort=expiration:asc
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;List secrets created in the previous week assuming same current time as above:&lt;/p&gt;
&lt;div class="highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;GET /v1/secrets?created=gt:2016-06-01T20:00:00Z,lt:2016-06-08T20:00:00Z
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;List secrets updated in the previous week assuming same current time as above:&lt;/p&gt;
&lt;div class="highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;GET /v1/secrets?updated=gt:2016-06-01T20:00:00Z,lt:2016-06-08T20:00:00Z
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The format of the data in the request and response will not change.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;This change should not impact the security of barbican, since it just provides
a way to narrow the results of querying the API.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h3&gt;Notifications &amp;amp; Audit Impact&lt;/h3&gt;
&lt;p&gt;This change does not impact the notifications or auditing features of barbican.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="python-and-command-line-client-impact"&gt;
&lt;h3&gt;Python and Command Line Client Impact&lt;/h3&gt;
&lt;p&gt;Both python-barbicanclient and the plugin for the unified CLI will need to be
updated to provide a way for clients to use these new filters.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;No additional end user impact should result from this change.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;The implementation should not use additional database queries, but rather use
the existing queries so that performance is not negatively impacted.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;This change should not affect deployers.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Developers should not be impacted since these filters are optional.  However,
developers could make use of these filters when applicable to their use
cases.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Douglas Mendizábal&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Joe Savak&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Update controllers to accept and make use of the new filters&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update documentation to include the newly added filters&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update python-barbicanclient to make use of the new filters&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update the unified CLI plugin to make use of the new filters&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;New functional and unit tests that exercise the new functionality should be
included in the implementation of this spec.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;The API change will need to be updated in the API reference as well as the
user guide.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;API Working Group’s Guideline for Pagination, Filtering and Sorting:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://git.openstack.org/cgit/openstack/api-wg/tree/guidelines/pagination_filter_sort.rst"&gt;https://git.openstack.org/cgit/openstack/api-wg/tree/guidelines/pagination_filter_sort.rst&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;ISO 8601 in Wikipedia:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://en.wikipedia.org/wiki/ISO_8601"&gt;https://en.wikipedia.org/wiki/ISO_8601&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 09 Apr 2020 00:00:00 </pubDate></item><item><title>Snakeoil CA Certificate Manager Plugin</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/kilo/snakeoil-ca.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/barbican-snakeoil-ca"&gt;https://blueprints.launchpad.net/barbican/+spec/barbican-snakeoil-ca&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A certificate management plugin which auto approves all requests can be very
useful for testing and development deployments. This is especially useful for
tools (such as TripleO) which hope to use Barbican as an abstraction layer for
certificate creation in production deployments but still require a
configuration that will work in CI.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;In order to use the certificate management interface in a development or
testing environment a user must (currently) configure dogtag or another backend
in a way which auto-approves certificate requests. This is an unnecessary
burden in many environments (such as CI pipelines) which require none of the
advanced features these tools provide.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Create a plugin which implements the certificate manager interface and will
sign any certificate request sent to it. Allow for configuration of an
on-disk CA certificate and key. If no certificate or key is found at that path,
a new CA certificate and key will be created and stored at that path encoded
in PEM file format. If no certificate or key path is specified then a new CA
key and certificate will be created and stored only in memory.&lt;/p&gt;
&lt;p&gt;Serial numbers for certificates will be generated from UUIDs.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;By limiting the scope of this plugin to non production uses, and only
certificate signing (no revokation, for example) there ends up being a small
amount of code using the PyOpenSSL library (an ffi for openssl). The amount
of code here is comprable to the amount required to shell out to a tool like
CA.pl and is considerable easier to read, understand, and test. If the scope
of this tool was ever expanded then we may want to reconsider using PyOpenSSL.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;A certificate order:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"certificate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"meta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"request_data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"PEM encoded X509 Request with optional X509Name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;This feature is explicitly not intended for use in any type of production
environment. This will be explicitly documented as such and is also named
‘Snakeoil’ to (hopefully) make this as apparent as possible.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h3&gt;Notifications &amp;amp; Audit Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None. This feature should never be deployed to production.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;This should ease the setup of development environments for certificate
management. We may want to consider documenting setting up this type of
environment for new users.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;This is implemented using PyOpenSSL and the motivation for this is explained
in the ‘Alternatives’ section.&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/140575"&gt;https://review.openstack.org/#/c/140575&lt;/a&gt;&lt;/p&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;greghaynes &amp;lt;&lt;a class="reference external" href="mailto:greg%40greghaynes.net"&gt;greg&lt;span&gt;@&lt;/span&gt;greghaynes&lt;span&gt;.&lt;/span&gt;net&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Implement the plugin. This plugin will implement the general certificate
request API so barbican-client work will be completed in that fashion.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Documenting this feature for setting up development and testing environments
could be useful but is not required.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;/section&gt;
</description><pubDate>Wed, 16 Jan 2019 00:00:00 </pubDate></item><item><title>Add cron job garbage collector for barbican database</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/mitaka/database-cleanup.html</link><description>

&lt;p&gt;Blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/clean-db-soft-deletes"&gt;https://blueprints.launchpad.net/barbican/+spec/clean-db-soft-deletes&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;For all tables in the barbican database that use soft deletion,
the entries in the table are not removed but flagged for deletion. We
want to create a configurable command that will be called by a cron job to
go through the database and delete entries where
the deleted flag equals 1 or if the entry is not needed anymore (like zombie
projects).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Create a barbican command called ‘barbican-manage db cleanup’ that will be run
by a cron job to clean up soft deletions in the barbican database. The command
will utilize python sqlalchemy libary calls to go through the database and
remove entries where deleted equals 1. The only tables that will be checked are
tables which have a corresponding class in ‘barbican/model/models.py’ and the
class has ‘SoftDeleteMixIn’ as a parent class. Any other table will not be
checked due to the assumption that soft deletes are not used. The
script will dynamically load in the table classes defined in models.py to a
list. Once the list is created, the script will then check the configuration
in barbican.conf to add or remove specific models.&lt;/p&gt;
&lt;p&gt;An example cron job file will be provided so that the administrator can modify
the contents to call the python script in intervals to their liking. It is
intended that the barbican deployer calls the barbican-mange db cleanup command
in a cron job.&lt;/p&gt;
&lt;p&gt;The command is configurable for these options:
minimum number of days to keep since soft deletion (default is 90 days)
delete zombie projects (no associated resources and default is true)
models to force check (no inheritence of SoftDeleteMixIn and default is None)
models to ignore (have inheritence of SoftDeleteMixIn and default is None)
log levels for log (default is INFO).
location of cleanup log (default is None).&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;note on zombie projects:
Barbican will create a project entry anytime a user
tries to make a request. If there are no resources
associated with a project, then that project
database entry can be removed.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;note on audit logging:
DELETEs via API are already logged by the CADF middleware. So there
should be no reason to add functionality to make an audit log
of who performed deletions.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;For this iteration, orders will not be touched due to different
available SLAs that barbican offerings could have and should be
discussed further. Certificate orders should not be
deleted because certificate renewals require the old orders.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Configuration -
Option parameters can be passed with the barbican manage command
to customize cleanup.
For example:
‘barbican db cleanup –min_num_days_to_keep_softdeletes 30’&lt;/p&gt;
&lt;p&gt;The command can also pass in a configuration file for a command.
‘barbican db cleanup -f “/etc/barbican/barbican.conf”&lt;/p&gt;
&lt;p&gt;The option parameters will have higher precedence than the variables
in the conf file if both the conf file and other options are given
as parameters. So the barbican admin can give only option parameters,
only a conf file, or both. The default value for the configuration file
will be ‘None’.&lt;/p&gt;
&lt;p&gt;Below is an example of how a configuration file can be configured:&lt;/p&gt;
&lt;p&gt;[db_cleanup]
#how long to keep the entry in the database after a soft deletion
minimum_num_days_to_keep_soft_deletions = 90&lt;/p&gt;
&lt;p&gt;#remove projects that have no associated resources
cleanup_unassociated_projects = True&lt;/p&gt;
&lt;p&gt;#table classes to force check  e.g., CertificateAuthority,SecretACL,..
table_classes_to_force_check = None&lt;/p&gt;
&lt;p&gt;# If a secret is expired, then it should be soft deleted
soft_delete_expired_secrets = True&lt;/p&gt;
&lt;p&gt;#table classes to ignore, their parent class is SoftDeleteMixIn
#e.g, Project,Secret…
table_classes_to_ignore = None&lt;/p&gt;
&lt;p&gt;# Show more verbose log output (sets INFO log level output)
verbose = True&lt;/p&gt;
&lt;p&gt;# Show debugging output in logs (sets DEBUG log level output)
#debug = True&lt;/p&gt;
&lt;p&gt;#log file to store information on deletions
db_cleanup_log_file = “/var/log/barbican/barbican-cleanup.log”&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Add a REST API parameter for delete operations where users can specify hard
deletion.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Leave it to the database admins to clean up their database manually.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Leave it to the database admin to create database triggers for cleanup.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a daemon instead of a cron job which is similar to the
glance scrubber.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;The data models should not change.&lt;/p&gt;
&lt;p&gt;The tables that are checked are tables which have a class that has
SoftDeleteMixIn as a parent class. Other tables will be ignored unless
configured. Entries where ‘deleted == 1’ will be removed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;The barbican manage command and cron job file should have valid
barbican admin user permissions. No global user should
be able to modify/run the script.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h3&gt;Notifications &amp;amp; Audit Impact&lt;/h3&gt;
&lt;p&gt;A log should be kept with total entries deleted for each table. The
log location will be configurable.&lt;/p&gt;
&lt;p&gt;If the level of logging is debug, then the table name,
id of entry, soft deletion date, and hard deletion date will be recorded.&lt;/p&gt;
&lt;p&gt;Since user deletions are already logged by CADF middleware,
it will not be necessary to log who made the soft deletions.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="python-and-command-line-client-impact"&gt;
&lt;h3&gt;Python and Command Line Client Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Since this is a recurring find and delete operation on a database,
this may take up a great amount of compute cycles. It will be up to
the admin/operator of Barbican to find the best time to run,
what interval to run the job, and configure how much to delete.
The admin will have to customize the cron job entry to their liking.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;The deployer will have to configure the cron job file.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;edtubill&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Each phase listed below is intended to be a CR. (Phase 2 will be split
into different CRs)&lt;/p&gt;
&lt;p&gt;Phase 1: Create simple barbican-manage command to go through
the database and delete everything with ‘deleted == 1’. Create unit and
functional tests for this first phase.
Phase 2: Add logic to read configuration file and go through database based on
the configuration. Create additional unit and functional tests.
Phase 4: Create example cron job configuration files
Phase 5: Document the cron job garbage collector on Barbican Wiki&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests must be written for internal component testing.
Functional tests must be created based on different possible
configurations. The functional tests will check the entries of
the database directly.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Wiki documentation will be created for usage of the ‘barbican-manage db cleanup’
command, how to configure, and examples on how to setup a cron job
will be provided.&lt;/p&gt;
&lt;p&gt;If a user does barbican-manage db cleanup –help, then usage documentation
should be shown.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/clean-db-soft-deletes"&gt;https://blueprints.launchpad.net/barbican/+spec/clean-db-soft-deletes&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Sun, 13 Jan 2019 00:00:00 </pubDate></item><item><title>Add auditing capability via CADF based notification events</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/liberty/audit-cadf-events.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/audit-cadf-events"&gt;https://blueprints.launchpad.net/barbican/+spec/audit-cadf-events&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This proposal is to add auditing capability in Barbican using CADF (Cloud Audit
Data Federation) specification. The idea is to identify auditable attributes and
construct audit data record as per CADF event specification and provide delivery
option via OpenStack notification framework to interested services and consumers.&lt;/p&gt;
&lt;p&gt;DMTF CADF standard provides auditing capabilities for compliance with security,
operational and business processes. See References section in end for more details
around CADF specification.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Large number of enterprise faces challenge when moving to OpenStack cloud.
And most of these challenges have nothing to do with OpenStack service capabilities.
Instead, the challenges are in terms of auditing and monitoring their workload and
data in accordance with their strict corporate, industry or regional policies and
compliance requirements (FIPS-140-2, PCI-DSS, SoX, ISO 27017 etc).
Barbican, being a security component in a cloud, has similar auditing requirement.&lt;/p&gt;
&lt;p&gt;In addition, Barbican has this concept of soft deletes where it keeps resources in
database even after they are marked deleted and are no longer used in live systems.
The idea is to have a sense of audit trail of its resources state. This approach
does not provide much value in terms of audit other than when it was marked deleted.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;To add auditing capability in Barbican, proposal is to leverage a existing standard
instead of creating own semantics and audit data model. In OpenStack ecosystem,
number of services (Ceilometer, Keystone) are using CADF based event data model to
report activities on its resources. Using CADF standard for auditing will allow
consistent reporting across services and will allow customers to use common audit
tools and processes for their audit data.&lt;/p&gt;
&lt;p&gt;The CADF model can answer critical questions about activity or event happening on
rest resources in a normative manner using CADF’s seven W’s of auditing (What,
When, Who, On What, Where, From Where, To Where). See Auditing Event Details section
below.&lt;/p&gt;
&lt;p&gt;The overhead of adding audit data interaction can be minimized by publishing
audit event as OpenStack notifications where event publisher does not have to wait
for response/ acknowledgment. This way audit event delivery is decoupled and can
still benefit from messaging infrastructure durability and delivery guarantees.&lt;/p&gt;
&lt;section id="auditing-event-details"&gt;
&lt;h3&gt;Auditing Event Details&lt;/h3&gt;
&lt;p&gt;Audit event data is constructed using who initiated request, request outcome, resource
operated on, resource identifier and event type information. Following is sample
of seven W's of auditing values for Barbican rest resources.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;W Component&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Resource&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;CADF
Properties&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Possible
Values&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;What&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST/PUT/
DELETE
v1/secrets&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;event.type
event.outcome&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;activity/monitor/control
success/failure/pending&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;When&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;td&gt;&lt;p&gt;event.eventTime&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;{event generation timestamp}&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Who&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;td&gt;&lt;p&gt;initiator.id
initiator.type
initiator.project_id&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;{token user id}
service/security/account/user
{scoped token project id}&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;From Where&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;td&gt;&lt;p&gt;initiator.host
initiator.agent&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;environemnt REMOTE_ADDR
environment HTTP_USER_AGENT&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;On What&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;td&gt;&lt;p&gt;target.id
target.type&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;resource id (secret/container)
data/keymgr/secret&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Where&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;td&gt;&lt;p&gt;observer.id
observer.type&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;target
service/keymgr&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;To Where&lt;/p&gt;&lt;/td&gt;
&lt;td/&gt;
&lt;td/&gt;
&lt;td/&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;CADF extension properties (mentioned below) can be used to capture domain specific
data available as part of rest request. Currently there is no plan to add these
properties as this may need per resource awareness in common decorator logic.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;event.attachments (structured or unstructured data)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;event.tags (domain specific identifiers/ classifications)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;pyCADF changes&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Creation of audit event requires oslo pyCADF library. pyCADF library needs to be
updated to reflect Barbican specific resource types. As per pyCADF contributors,
either use existing types or create very few new generic types. Following Barbican
specific resource types are going to be added in pyCADF resource taxonomy.&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;data/keymgr/secret&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;data/keymgr/container&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;data/keymgr/order&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;data/keymgr  - general placeholder for all other remaining resourcs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;service/keymgr&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Above types are going to be added in pyCADF taxonomy as mentioned in link below.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;pyCADF resource taxonomy
&lt;a class="reference external" href="https://github.com/openstack/pycadf/blob/master/pycadf/cadftaxonomy.py#L111"&gt;https://github.com/openstack/pycadf/blob/master/pycadf/cadftaxonomy.py#L111&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="audit-event-generation"&gt;
&lt;h3&gt;Audit Event Generation&lt;/h3&gt;
&lt;p&gt;For API requests, audit event are going to be generated using audit middleware approach.
This middleware is now available as part of keystonemiddleware (&amp;gt; 1.5) library. This
library has Keystone middleware which is used by Barbican for Keystone token validation.&lt;/p&gt;
&lt;p&gt;Audit middleware is going to create two events per Barbican REST API invocation. One with
information extracted from request data and the second correlated one with request outcome
(response). The mapping information is going to be managed via barbican specific configuration
file which is going to be similar to files described in following pycadf samples link.
&lt;a class="reference external" href="https://github.com/openstack/pycadf/tree/master/etc/pycadf"&gt;https://github.com/openstack/pycadf/tree/master/etc/pycadf&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For asynchronous task processing workers, audit event is constructed using task related
data. It can be implemented as a decorator which can be added to each task common
methods (handle_processing, handle_success and handle_error) or can be added on base task
process method. This audit event is going to be published as notification to same queue
which is used by audit middleware as well.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="audit-event-delivery"&gt;
&lt;h3&gt;Audit Event Delivery&lt;/h3&gt;
&lt;p&gt;Internally audit middleware uses an oslo messaging based notifier to publish CADF
events to configured messaging infrastructure. Audit decorators will use similar
approach.&lt;/p&gt;
&lt;p&gt;Audit middleware is added to Barbican request pipeline via additional filter in
&lt;cite&gt;barbican-api-paste.ini&lt;/cite&gt; where related audit mapping file path is defined. Delivery of
audit event via decorator needs to be configurable as developer boxes may not necessarily
have the needed setup. By default, audit delivery as notification is going to disabled.&lt;/p&gt;
&lt;p&gt;The oslo messaging framework supports publish of this audit data to messaging queue via
‘messagingv2’ driver or can be written to log files via its ‘log’ driver.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;We could rely on Barbican existing logging but that does not provide a complete
and consistent picture of service audit data. Non-standard logging means that cloud
provider need service specific audit tools to aggregate and analyze the logs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;This improves security in the stack by providing audit capability. This will
help in addressing some of compliance requirements expected from Barbican service.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h3&gt;Notifications &amp;amp; Audit Impact&lt;/h3&gt;
&lt;p&gt;Will have additional notification capability to publish audit events.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Audit events are published as notifications to queue and does not have to wait for
response/acknowledgment so overall associated overhead should be very minimal.
When notifications are written to log files, related overhead should still be low and
can be comparable to logic of adding 2 log statements.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;To enable audit event delivery via notifications, deployer will need to change
default configuration.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;Assignee(s)&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;arunkant&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add new blueprint and update oslo pyCADF library.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Define pipeline filter with audit map configuration file barbican_api_audit_map.conf&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add new decorator to create CADF event data for asynchronous worker processing logic.
Add decorator to related worker task methods.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add ability to turn on audit event generation. By default it needs to be off.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;pyCADF library (with barbican specific updated taxonomy).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;The new unit tests are going to be added for middleware and order processing flow.
For middleware unit tests, configuration override is needed for paste and api ini files.
Oslo test driver &lt;a class="reference external" href="https://github.com/openstack/oslo.messaging/blob/master/oslo_messaging/notify/_impl_test.py"&gt;https://github.com/openstack/oslo.messaging/blob/master/oslo_messaging/notify/_impl_test.py&lt;/a&gt;
can be used to verify message content in addition to mock patched methods approach.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;CADF event usage should be documented. For order processing flow, document what audit
related changes, if any, are needed to add audit support for new order types.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;CADF Working Group. &lt;a class="reference external" href="http://www.dmtf.org/standards/cadf"&gt;http://www.dmtf.org/standards/cadf&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CADF representation for OpenStack
&lt;a class="reference external" href="http://www.dmtf.org/sites/default/files/standards/documents/DSP2038_1.0.0.pdf"&gt;http://www.dmtf.org/sites/default/files/standards/documents/DSP2038_1.0.0.pdf&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Audit Middleware
&lt;a class="reference external" href="https://docs.openstack.org/developer/keystonemiddleware/audit.html"&gt;https://docs.openstack.org/developer/keystonemiddleware/audit.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PyCADF developer docs
&lt;a class="reference external" href="https://docs.openstack.org/developer/pycadf/"&gt;https://docs.openstack.org/developer/pycadf/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CADF event model and taxonomies
&lt;a class="reference external" href="https://wiki.openstack.org/w/images/e/e1/Introduction_to_Cloud_Auditing_using_CADF_Event_Model_and_Taxonomy_2013-10-22.pdf"&gt;https://wiki.openstack.org/w/images/e/e1/Introduction_to_Cloud_Auditing_using_CADF_Event_Model_and_Taxonomy_2013-10-22.pdf&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ceilometer CADF support
&lt;a class="reference external" href="https://wiki.openstack.org/wiki/Ceilometer/blueprints/support-standard-audit-formats"&gt;https://wiki.openstack.org/wiki/Ceilometer/blueprints/support-standard-audit-formats&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Tue, 27 Nov 2018 00:00:00 </pubDate></item><item><title>Refactor Client Entity Models</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/juno/client-refactor-models.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/python-barbicanclient/+spec/client-refactor-models"&gt;https://blueprints.launchpad.net/python-barbicanclient/+spec/client-refactor-models&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The current Entity Models in the client are a bit awkward to use.  This
blueprint proposes refactoring some functionality to make the API more
usable and consistent.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;The Entity Models in &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;barbicanclient&lt;/span&gt;&lt;/code&gt; should be refactored to provide a
more Pythonic api.  This refactor will make the existing Entities consistent
with the recently approved Containers blueprint. &lt;a class="footnote-reference brackets" href="#id2" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id2" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://specs.openstack.org/openstack/barbican-specs/specs/juno/client-add-containers.html"&gt;https://specs.openstack.org/openstack/barbican-specs/specs/juno/client-add-containers.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Refactor existing Models to provide methods for actions that affect a single
entity inside the entity class.  This will allow for worflows that only affect
a single entity to be completed without the need for a reference to the
corresponding &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;EntityManager&lt;/span&gt;&lt;/code&gt; subclass.&lt;/p&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Secret&lt;/span&gt;&lt;/code&gt; entity should be refactored to add a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;store()&lt;/span&gt;&lt;/code&gt; method and
a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;payload&lt;/span&gt;&lt;/code&gt; property:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;barbicanclient&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;

&lt;span class="c1"&gt;# Set up client connection&lt;/span&gt;
&lt;span class="n"&gt;connection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tenant_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;endpoint&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ENDPOINT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;insecure&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Create a new Secret&lt;/span&gt;
&lt;span class="n"&gt;my_secret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Secret&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"My secret name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                      &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"the secret sauce"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;my_secret&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# Alternatively set Secret properties instead of passing args&lt;/span&gt;
&lt;span class="n"&gt;my_secret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Secret&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;my_secret&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"My secret name"&lt;/span&gt;
&lt;span class="n"&gt;my_secret&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"the secret sauce"&lt;/span&gt;
&lt;span class="n"&gt;my_secret&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Similarly, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Orders&lt;/span&gt;&lt;/code&gt; should allow both args to the constructor as well as
setting properties directly.  We should also add a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;submit()&lt;/span&gt;&lt;/code&gt; method to
submit the order to the API:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;barbicanclient&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;

&lt;span class="c1"&gt;# Set up client connection&lt;/span&gt;
&lt;span class="n"&gt;connection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tenant_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;endpoint&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ENDPOINT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;insecure&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Create and submit a new Order&lt;/span&gt;
&lt;span class="n"&gt;my_order&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"My Order"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;payload_content_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"application/octet-stream"&lt;/span&gt;
    &lt;span class="n"&gt;algorithm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"AES"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"CBC"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;bit_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;expiration&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;my_order&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;submit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# Alternatively set the Order properties instead of passing args&lt;/span&gt;
&lt;span class="n"&gt;my_order&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;my_order&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"My Order"&lt;/span&gt;
&lt;span class="n"&gt;my_order&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;payload_content_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"application/octet-stream"&lt;/span&gt;
&lt;span class="n"&gt;my_order&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;algorithm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"AES"&lt;/span&gt;
&lt;span class="n"&gt;my_order&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"CBC"&lt;/span&gt;
&lt;span class="n"&gt;my_order&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bit_length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;256&lt;/span&gt;
&lt;span class="n"&gt;my_order&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;expiration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;
&lt;span class="n"&gt;my_order&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;submit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Listing entities should still be handled via the corresponding
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;EntityManager&lt;/span&gt;&lt;/code&gt;.  The ability to decrypt a secret, however, should be moved
to the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Secret&lt;/span&gt;&lt;/code&gt; class, and removed from the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;SecretManager&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Retrieving entities should be moved from the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;EntityManager&lt;/span&gt;&lt;/code&gt; (replacing
the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;get()&lt;/span&gt;&lt;/code&gt; function) to the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Entity&lt;/span&gt;&lt;/code&gt; constructor. For example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;my_secret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Secret&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;secret_ref&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;SECRET_REF&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;my_order&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order_ref&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ORDER_REF&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Deleting entities can either be done with the existing &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;EntityManager&lt;/span&gt;&lt;/code&gt;
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;delete(entity_ref)&lt;/span&gt;&lt;/code&gt; or with a new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;Entity&lt;/span&gt;&lt;/code&gt; function, &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;delete()&lt;/span&gt;&lt;/code&gt;.
An example using a Secret:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="c1"&gt;# New method&lt;/span&gt;
&lt;span class="n"&gt;my_secret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Secret&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;secret_ref&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;SECRET_REF&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;my_secret&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# Old way still works&lt;/span&gt;
&lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;secret_ref&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;SECRET_REF&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;We could continue to use the objects as they currently exist.&lt;/p&gt;
&lt;p&gt;Also note that the Orders functionality will need to be revisited once
the Typed Orders implementation lands. &lt;a class="footnote-reference brackets" href="#id4" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id4" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://specs.openstack.org/openstack/barbican-specs/specs/juno/api-orders-add-more-types.html"&gt;https://specs.openstack.org/openstack/barbican-specs/specs/juno/api-orders-add-more-types.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h3&gt;Notifications &amp;amp; Audit Impact&lt;/h3&gt;
&lt;p&gt;Logging should be done in a manner consistent with the rest of the library.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;This change will require rewriting how Secret objects are consumed, and will
require a new major version for the client library.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Blueprint Draft: Douglas Mendizábal (redrobot)
Implementation: Adam Harwell (rm_work)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Refactor Secret entity&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Refactor Order entity&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Testing should be consistent with existing testing in the library.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Common workflows will have to be updated to give examples on how to use
the refactored classes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;Containers in the Client etherpad: &lt;a class="reference external" href="https://etherpad.openstack.org/p/python-barbicanclient-containers"&gt;https://etherpad.openstack.org/p/python-barbicanclient-containers&lt;/a&gt;
Containers Blueprint: &lt;a class="reference external" href="https://specs.openstack.org/openstack/barbican-specs/specs/juno/client-add-containers.html"&gt;https://specs.openstack.org/openstack/barbican-specs/specs/juno/client-add-containers.html&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Wed, 14 Nov 2018 00:00:00 </pubDate></item><item><title>Consume Keystone Project Delete Events</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/juno/consume-keystone-events.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/consume-keystone-events"&gt;https://blueprints.launchpad.net/barbican/+spec/consume-keystone-events&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In most of openstack deployments, barbican is expected to be integrated with
keystone for its resource authorization needs. Keystone and barbican share
keystone project as a common entity reference. Which means, project needs to
exist in keystone before barbican resources (e.g. secrets and containers) can
be added for that project. But when project is deleted in keystone, there is
no action taken by barbican to reflect the change and it keep maintaining that
project dangling resource references as-is. This blueprint is addressing
related issues in this area.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Barbican resources are managed at keystone project level. As part of barbican
resource creation, barbican tenant (a.k.a. project) is mapped to keystone
project and resource is associated with the tenant. Over time, many more
resources are added to the tenant. Now when project is deleted from keystone,
currently barbican stays unaware of that change and keeps its resources as-is.
Those project resources are now invalid and are kind of dangling references to
a non existing project.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;As barbican feature set expands, the amount of such tenant resources will
grow over time which can negatively impact performance of db operations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hardware Security Modules (HSM) has a upper limit on the number of key
encryption keys it can store. These numbers are correlated to number of
projects in barbican. Without project status awareness, related invalid keys
cleanup cannot be done to reclaim space for new keys in HSM.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In a corner case of PKI token service usage, for a small time window,
unexpired PKI token(s) can access a deleted project resource as it has yet
to fetch and process related revocation events from keystone. By making
barbican aware of deleted projects, even those PKI token would not have
access to barbican resources. Just to be clear, in general PKI token would
not have this issue if revocation events are fetched pretty frequently.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Keystone publishes notifications whenever a project is created, updated and
deleted. Proposal is to add notification listener in barbican to consume
keystone public events.&lt;/p&gt;
&lt;p&gt;Keystone event payload has project id as resource_info and barbican event
listener logic will propagate it to make changes on resources associated with
that project.&lt;/p&gt;
&lt;p&gt;Following is keystone sample notification on project delete:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ctxt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[{}],&lt;/span&gt; &lt;span class="n"&gt;metadata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="s1"&gt;'timestamp'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'2014-06-12 00:20:03.584997'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'message_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'1ade0b2b-1584-48b9-a026-64bd06659baf'&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;severity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;publisher_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;identity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;arunkant&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;uws&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;event_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;identity&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;deleted&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'resource_info'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;u&lt;/span&gt;&lt;span class="s1"&gt;'00ac7ea2a1a3486284c8e2af27b7bc9e'&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Event listener will use oslo messaging library which provides a abstraction to
allow usage of different type of messaging transport.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Deletion of a keystone project will invoke delete on related secret(s),
container(s), tenant entity. Currently entity delete is a soft delete as
specific fields are marked deleted but the record remains in datastore. In
the event that a project is disabled, Keystone will invalidate the tokens for
that project and the secrets owned by that project will be inaccessible.
The secrets owned by Barbican won’t be soft deleted but they will be
unreachable. Also, the keystone delete project and the barbican delete
project should both generate CADF audit events and ideally a correlation
identifier should be used between these two events. Also an extension field
in the audit record should be used to declare the type of delete (soft
or hard).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Keystone sends various notification events based on its own resource types
(e.g. user, project, role etc.) and type of operation (e.g. created,
updated, deleted etc.). This proposal scope is to act on keystone project
delete event &lt;em&gt;only&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Barbican will add a queue to exchange to listen keystone notifications.
Queue specific attributes e.g. exchange name and type, queue name, binding
pattern etc. are going to be configurable in barbican configuration. Some of
these attribute values need to align with keystone notification
configuration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Keystone currently publishes notification only with &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;info&lt;/span&gt;&lt;/code&gt; severity. The
binding pattern of &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;notifications.*&lt;/span&gt;&lt;/code&gt; will handle that.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Barbican queue is going to be durable to survive broker restart.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This feature is going to be configurable and not enabled by default similar
to keystone authentication via pipeline configuration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Notifications are acknowledged only when barbican listener has processed
event information. Auto-acknoledgement is going to be &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;false&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Barbican connection to message queue is authenticated using username and
password. These credentials are going to be defined as part of barbican
configuration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Depending on SSL support available in oslo messaging for a specific
transport provider, related configuration is going to be added in barbican
configuration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In initial version, there is no trust established between messaging queue
and barbican instance(s). KDS (Key distribution service, Kite) may help
around this in future once other services start using it for this kind of
functionality.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Changes on resource side will be committed only when complete event
processing is done otherwise change will be rolled back.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once such event support is available in barbican, those events can be
propagated to barbican’s external sub-components if it makes sense. One
example of such sub-comonent can be clean up of key encryption keys in HSM
(when this feature is added in future).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;There can be other ways to get keystone project information like polling model
or accessing keystone datastore directly but there are not scalable and may
introduce tight coupling between services. Events based asynchronous approach
is better as keystone notifications are primarily intended for other openstack
services to take action based on events e.g. cleanup of their resources.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;There is no data model impact as we are going to utilize existing entity soft
delete functionality.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;A keystone public event does not contain sensitive data by itself. Event data
has information about operation and resource id.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;As implication of those events will result in deleting barbican resources
so clear logging of events and action taken will be needed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once auditing support is added in barbican, the project delete event will
be one type of audit activity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Message queue connection information needs to be secured similar to other
external resources connections e.g. database.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h3&gt;Notifications &amp;amp; Audit Impact&lt;/h3&gt;
&lt;p&gt;A new notification listener is added. Related auditing information is going to
be added to system.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;There should not be performance impact other than new message handling server
is added on same host system.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;As result of this change, barbican number of connections to db system may
increase depending on load of actionable events. Generally the number of
such events will be quite less considering keystone projects are likely not
to deleted regularly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Depending on keystone event activity, a deployer can choose to enable
notification listener on some of barbican instances assuming there is pool
of barbican instances in a setup.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;This feature needs to be enabled as default configuration will have it
disabled.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Related notification listener configuration needs to be configured as per
deployer’s existing messaging infrastructure setup.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A message handling server is added, as a new process, to transport
notification events from queue to barbican.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Arun Kant &amp;lt;&lt;a class="reference external" href="mailto:arun.kant%40hp.com"&gt;arun&lt;span&gt;.&lt;/span&gt;kant&lt;span&gt;@&lt;/span&gt;hp&lt;span&gt;.&lt;/span&gt;com&lt;/a&gt;&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;??&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Need to add notification listener configuration&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement notification listener and message handling server using oslo
messaging packages.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Identify actionable events and process to make changes on barbican
resources.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement these actions as a unit and rollback in case of a processing
error. One option, needs to be investigated, is to do all operations within
a SQLAlchemy session.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If missing, add checks in order and other resource API so that create and
update of resource is not allowed for deleted tenants (a.k.a. keystone
projects)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Add any integration test provided needed messaging support is available.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;There will be additional documentation around notification listener
configuration. Possibly a new option similar to following link&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/cloudkeep/barbican/wiki/Barbican-Options:-authentication-with-Keystone"&gt;https://github.com/cloudkeep/barbican/wiki/Barbican-Options:-authentication-with-Keystone&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/developer/oslo.messaging/notification_listener.html"&gt;https://docs.openstack.org/developer/oslo.messaging/notification_listener.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/developer/oslo.messaging/index.html"&gt;https://docs.openstack.org/developer/oslo.messaging/index.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/developer/oslo.messaging/notification_listener.html#oslo.messaging.MessageHandlingServer"&gt;https://docs.openstack.org/developer/oslo.messaging/notification_listener.html#oslo.messaging.MessageHandlingServer&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Wed, 14 Nov 2018 00:00:00 </pubDate></item><item><title>Add worker retry and future updates support</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/kilo/add-worker-retry-update-support.html</link><description>

&lt;p&gt;Launchpad blueprint:
&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/add-worker-retry-update-support"&gt;https://blueprints.launchpad.net/barbican/+spec/add-worker-retry-update-support&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The Barbican worker processes need a means to support retrying failed yet
recoverable tasks (such as when remote systems are unavailable) and for
handling updates for long-running order processes such as certificate
generation. This blueprint defines the requirements for this retry and update
processing, and proposes an implementation to add this feature.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Barbican manages asynchronous tasks, such as generating secrets, via datastore
tracking entities such as orders (currently the only tracking entity in
Barbican). These entities have a status field that tracks their state, starting
with PENDING for new entities, and moving to either ACTIVE or ERROR states for
successful or unsuccessful termination of the asynchronous task respectively.&lt;/p&gt;
&lt;p&gt;Barbican worker processes implement these asynchronous tasks, as depicted on
this wiki page: &lt;a class="reference external" href="https://github.com/cloudkeep/barbican/wiki/Architecture"&gt;https://github.com/cloudkeep/barbican/wiki/Architecture&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As shown in the diagram, a typical deployment can include multiple worker
processes operating in parallel off a tasking queue. The queue invokes task
methods on the worker processes via RPC. In some cases, these invoked tasks
require the entity (eg. order) to stay PENDING, either to allow for follow on
processing in the future or else to retry processing due to a temporary
blocking condition (eg. remote service is not available at this time).&lt;/p&gt;
&lt;p&gt;The following are requirements for retrying tasks in the future and thus
keeping the tracking entity in the PENDING state:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Barbican&lt;/span&gt; &lt;span class="n"&gt;needs&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;support&lt;/span&gt; &lt;span class="n"&gt;extended&lt;/span&gt; &lt;span class="n"&gt;workflow&lt;/span&gt; &lt;span class="n"&gt;processes&lt;/span&gt; &lt;span class="n"&gt;whereby&lt;/span&gt; &lt;span class="n"&gt;an&lt;/span&gt; &lt;span class="n"&gt;entity&lt;/span&gt;
     &lt;span class="n"&gt;might&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;PENDING&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;long&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;requiring&lt;/span&gt; &lt;span class="n"&gt;periodic&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="n"&gt;checks&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;
     &lt;span class="n"&gt;see&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;workflow&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;completed&lt;/span&gt;

&lt;span class="n"&gt;R&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Barbican&lt;/span&gt; &lt;span class="n"&gt;needs&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;support&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;attempting&lt;/span&gt; &lt;span class="n"&gt;an&lt;/span&gt; &lt;span class="n"&gt;RPC&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="n"&gt;some&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt;
     &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;future&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;dependent&lt;/span&gt; &lt;span class="n"&gt;services&lt;/span&gt; &lt;span class="n"&gt;are&lt;/span&gt; &lt;span class="n"&gt;temporarily&lt;/span&gt; &lt;span class="n"&gt;unavailable&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note that this blueprint does not handle concurrent updates made to the
same entity, say to perform a periodic status check on an order and also apply
client updates to that same order. This will be addressed in a future
blueprint.&lt;/p&gt;
&lt;p&gt;Note also that this blueprint does not handle entities that are ‘stuck’ in the
PENDING state because of lost messages in the queue or workers that crash while
processing an entity. This will also be addressed in a future blueprint.&lt;/p&gt;
&lt;p&gt;In addition, the following non-functional requirements are needed in the final
implementation:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;NF&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;To&lt;/span&gt; &lt;span class="n"&gt;keep&lt;/span&gt; &lt;span class="n"&gt;entity&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="n"&gt;consistent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;one&lt;/span&gt; &lt;span class="n"&gt;worker&lt;/span&gt; &lt;span class="n"&gt;can&lt;/span&gt; &lt;span class="n"&gt;work&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="n"&gt;an&lt;/span&gt;
      &lt;span class="n"&gt;entity&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;manage&lt;/span&gt; &lt;span class="n"&gt;retrying&lt;/span&gt; &lt;span class="n"&gt;tasks&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="n"&gt;NF&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;For&lt;/span&gt; &lt;span class="n"&gt;resilience&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;worker&lt;/span&gt; &lt;span class="n"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt; &lt;span class="n"&gt;worker&lt;/span&gt; &lt;span class="n"&gt;process&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;cluster&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;workers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;able&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;
       &lt;span class="n"&gt;handle&lt;/span&gt; &lt;span class="n"&gt;retrying&lt;/span&gt; &lt;span class="n"&gt;entities&lt;/span&gt; &lt;span class="n"&gt;independently&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt; &lt;span class="n"&gt;worker&lt;/span&gt; &lt;span class="n"&gt;processes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;even&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;these&lt;/span&gt; &lt;span class="n"&gt;worker&lt;/span&gt; &lt;span class="n"&gt;processes&lt;/span&gt; &lt;span class="n"&gt;are&lt;/span&gt; &lt;span class="n"&gt;intermittently&lt;/span&gt; &lt;span class="n"&gt;available&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

    &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;If&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;worker&lt;/span&gt; &lt;span class="n"&gt;comes&lt;/span&gt; &lt;span class="n"&gt;back&lt;/span&gt; &lt;span class="n"&gt;online&lt;/span&gt; &lt;span class="n"&gt;after&lt;/span&gt; &lt;span class="n"&gt;going&lt;/span&gt; &lt;span class="n"&gt;down&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;able&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;
       &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="n"&gt;processing&lt;/span&gt; &lt;span class="n"&gt;retry&lt;/span&gt; &lt;span class="n"&gt;tasks&lt;/span&gt; &lt;span class="n"&gt;again&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;without&lt;/span&gt; &lt;span class="n"&gt;need&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;synchronize&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt;
       &lt;span class="n"&gt;other&lt;/span&gt; &lt;span class="n"&gt;workers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="n"&gt;NF&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt; &lt;span class="n"&gt;standalone&lt;/span&gt; &lt;span class="n"&gt;Barbican&lt;/span&gt; &lt;span class="n"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt;
      &lt;span class="n"&gt;possible&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;demonstrate&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;periodic&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="n"&gt;check&lt;/span&gt; &lt;span class="n"&gt;feature&lt;/span&gt; &lt;span class="n"&gt;via&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt;
      &lt;span class="n"&gt;SimpleCertificatePlugin&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;in&lt;/span&gt;
      &lt;span class="n"&gt;barbican&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plugin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;simple_certificate&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Manager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The following assumptions are made:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Accurate&lt;/span&gt; &lt;span class="n"&gt;retry&lt;/span&gt; &lt;span class="n"&gt;times&lt;/span&gt; &lt;span class="n"&gt;are&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;For&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;retried&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="n"&gt;minutes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="n"&gt;would&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt;
       &lt;span class="n"&gt;acceptable&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="n"&gt;was&lt;/span&gt; &lt;span class="n"&gt;actually&lt;/span&gt; &lt;span class="n"&gt;retried&lt;/span&gt; &lt;span class="n"&gt;after&lt;/span&gt; &lt;span class="n"&gt;more&lt;/span&gt; &lt;span class="n"&gt;than&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
       &lt;span class="n"&gt;minutes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;For&lt;/span&gt; &lt;span class="n"&gt;SSL&lt;/span&gt; &lt;span class="n"&gt;certificate&lt;/span&gt; &lt;span class="n"&gt;workflows&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;where&lt;/span&gt; &lt;span class="n"&gt;some&lt;/span&gt; &lt;span class="n"&gt;certificate&lt;/span&gt; &lt;span class="n"&gt;types&lt;/span&gt;
       &lt;span class="n"&gt;can&lt;/span&gt; &lt;span class="n"&gt;take&lt;/span&gt; &lt;span class="n"&gt;days&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;such&lt;/span&gt; &lt;span class="n"&gt;retry&lt;/span&gt; &lt;span class="n"&gt;delays&lt;/span&gt; &lt;span class="n"&gt;would&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt;
       &lt;span class="n"&gt;significant&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

    &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Relaxed&lt;/span&gt; &lt;span class="n"&gt;retry&lt;/span&gt; &lt;span class="n"&gt;schedules&lt;/span&gt; &lt;span class="n"&gt;allow&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;more&lt;/span&gt; &lt;span class="n"&gt;granular&lt;/span&gt; &lt;span class="n"&gt;retry&lt;/span&gt; &lt;span class="n"&gt;checking&lt;/span&gt;
       &lt;span class="n"&gt;intervals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;allow&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;delays&lt;/span&gt; &lt;span class="n"&gt;due&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;excessive&lt;/span&gt; &lt;span class="n"&gt;tasks&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;queues&lt;/span&gt;
       &lt;span class="n"&gt;during&lt;/span&gt; &lt;span class="n"&gt;busy&lt;/span&gt; &lt;span class="n"&gt;times&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

    &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Excessive&lt;/span&gt; &lt;span class="n"&gt;delays&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;retry&lt;/span&gt; &lt;span class="n"&gt;times&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;expected&lt;/span&gt; &lt;span class="n"&gt;could&lt;/span&gt; &lt;span class="n"&gt;indicate&lt;/span&gt; &lt;span class="n"&gt;that&lt;/span&gt;
       &lt;span class="n"&gt;worker&lt;/span&gt; &lt;span class="n"&gt;nodes&lt;/span&gt; &lt;span class="n"&gt;are&lt;/span&gt; &lt;span class="n"&gt;overloaded&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;This&lt;/span&gt; &lt;span class="n"&gt;blueprint&lt;/span&gt; &lt;span class="n"&gt;does&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt;
       &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;issue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;deferring&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;deployment&lt;/span&gt; &lt;span class="n"&gt;monitoring&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;scaling&lt;/span&gt;
       &lt;span class="n"&gt;processes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;This blueprint proposes that for requirements R-1 and R-2, the plugins used by
worker tasks (such as the certificate plugin) determine if tasks should be
retried and at what time in the future. If plugins determine that a task
should be retried, then these tasks will be scheduled for a future retry
attempt.&lt;/p&gt;
&lt;p&gt;To implement this scheduling process, this blueprint proposes using the Oslo
periodic task feature, described here:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/developer/oslo-incubator/api/openstack.common.periodic_task.html"&gt;https://docs.openstack.org/developer/oslo-incubator/api/openstack.common.periodic_task.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A working example implementation with an older code base is shown here:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://github.com/cloudkeep/barbican/blob/verify-resource/barbican/queue/server.py#L174"&gt;https://github.com/cloudkeep/barbican/blob/verify-resource/barbican/queue/server.py#L174&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Each worker node could then execute a periodic task service, that invokes a
method on a scheduled basis (configurable, say every 15 seconds). This method
would then query which tasks need to be retried (say if current time &amp;gt;=
retry time), and for each one issue a retry task message to the queue. Once
tasks are enqueued, this method would remove the retry records from the retry
list. Eventually the queue would invoke workers to implement these retry tasks.&lt;/p&gt;
&lt;p&gt;To provide a means to evaluate the retry feature in standalone Barbican per
NF-3, the SimpleCertificatePlugin class in
barbican.plugin.simple_certificate_manager.py would be modified to have the
issue_certificate_request() method return a retry time of 5 seconds
(configurable). The check_certificate_status() method would then return a
successful execution to terminate the order in the ACTIVE state.&lt;/p&gt;
&lt;p&gt;This blueprint proposes adding two entities to the data model: OrderRetryTask
and EntityLock.&lt;/p&gt;
&lt;p&gt;The OrderRetryTask entity would manage which tasks need to be retried on which
entities, and would have the following attributes:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Primary&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt;

&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;order_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;FK&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;retry&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="n"&gt;intended&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt;

&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;retry_task&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;RPC&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;invoke&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;retry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;This&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="n"&gt;could&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt;
               &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;different&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="n"&gt;than&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt; &lt;span class="n"&gt;one&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;such&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;support&lt;/span&gt;
               &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;SSL&lt;/span&gt; &lt;span class="n"&gt;certificate&lt;/span&gt; &lt;span class="n"&gt;plugin&lt;/span&gt; &lt;span class="n"&gt;checking&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;certificate&lt;/span&gt; &lt;span class="n"&gt;updates&lt;/span&gt;
               &lt;span class="n"&gt;after&lt;/span&gt; &lt;span class="n"&gt;initiating&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;certificate&lt;/span&gt; &lt;span class="n"&gt;process&lt;/span&gt;

&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;retry_at&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;timestamp&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;after&lt;/span&gt; &lt;span class="n"&gt;which&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;retry&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;

&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;retry_args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;send&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;retry_task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="n"&gt;This&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt; &lt;span class="n"&gt;includes&lt;/span&gt;
               &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;entity&lt;/span&gt; &lt;span class="n"&gt;ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;so&lt;/span&gt; &lt;span class="n"&gt;no&lt;/span&gt; &lt;span class="n"&gt;need&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;an&lt;/span&gt; &lt;span class="n"&gt;entity&lt;/span&gt; &lt;span class="n"&gt;FK&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;entity&lt;/span&gt;

&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;retry_kwargs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="n"&gt;JSON&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ified&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;kwargs&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;send&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;retry_task&lt;/span&gt;

&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;retry_count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;how&lt;/span&gt; &lt;span class="n"&gt;many&lt;/span&gt; &lt;span class="n"&gt;times&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt; &lt;span class="n"&gt;has&lt;/span&gt; &lt;span class="n"&gt;been&lt;/span&gt; &lt;span class="n"&gt;retried&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;New retry records would be added for tasks that need to be retried in the
future, as determined by the plugin as part of workflow processing. The next
periodic task method invocation would then send this task to the queue for
another worker to implement later.&lt;/p&gt;
&lt;p&gt;The EntityLock entity would manage which worker is allowed to delete from the
OrderRetryTask table, since per NF-1 above only one worker should be able to
delete from this table. This entity would have the following attributes:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;entity_to_lock&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;entity&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;lock&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'OrderRetryTask'&lt;/span&gt; &lt;span class="n"&gt;here&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
                   &lt;span class="n"&gt;This&lt;/span&gt; &lt;span class="n"&gt;would&lt;/span&gt; &lt;span class="n"&gt;be&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;primary&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;worker_host_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;worker&lt;/span&gt; &lt;span class="n"&gt;that&lt;/span&gt; &lt;span class="n"&gt;has&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt;
                     &lt;span class="n"&gt;OrderRetryTask&lt;/span&gt; &lt;span class="n"&gt;entity&lt;/span&gt; &lt;span class="s1"&gt;'locked'&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;

&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;When&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt; &lt;span class="n"&gt;was&lt;/span&gt; &lt;span class="n"&gt;locked&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This entity would only have zero or one records. So the periodic method above
would execute the following pseudo code:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Start&lt;/span&gt; &lt;span class="n"&gt;SQLAlchemy&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;transaction&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;Attempt&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;insert&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="n"&gt;into&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;EntityLock&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;
    &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rollback&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;Handle&lt;/span&gt; &lt;span class="s1"&gt;'stuck'&lt;/span&gt; &lt;span class="n"&gt;locks&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;see&lt;/span&gt; &lt;span class="n"&gt;paragraph&lt;/span&gt; &lt;span class="n"&gt;below&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;

&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;Query&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;retry&lt;/span&gt; &lt;span class="n"&gt;tasks&lt;/span&gt;
    &lt;span class="n"&gt;Send&lt;/span&gt; &lt;span class="n"&gt;retry&lt;/span&gt; &lt;span class="n"&gt;tasks&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;queue&lt;/span&gt;
    &lt;span class="n"&gt;Remove&lt;/span&gt; &lt;span class="n"&gt;enqueued&lt;/span&gt; &lt;span class="n"&gt;retry&lt;/span&gt; &lt;span class="n"&gt;tasks&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;OrderRetryTask&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;
    &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rollback&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;finally&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;Remove&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;EntityLock&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;
    &lt;span class="n"&gt;Clear&lt;/span&gt; &lt;span class="n"&gt;SQLAlchemy&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;transaction&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Lock tables can be problematic if the locking process crashes without removing
the locks. The overall time a worker holds on to a lock should be brief
however, so the lock attempt rollback process above should check for and remove
a stale lock based on the ‘created_at’ time on the lock.&lt;/p&gt;
&lt;p&gt;To separate coding concerns, it makes sense to implement this process in a
separate Oslo ‘service’ server process, similar to the &lt;a class="reference external" href="https://github.com/openstack/barbican/blob/master/barbican/queue/keystone_listener.py#L130"&gt;Keystone listener
approach&lt;/a&gt;
This service would only run the Oslo periodic task method, to perform the retry
updating process. If the method failed to operate, say due to another worker
locking resource, it could just return/exit. The next periodic call would then
start the process again.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Rather than having each worker process manage retrying tasks, a separate node
could be designated to manage these retries. This would eliminate the need for
the EntityLock entity. However, this approach would require configuring yet
another node in the Barbican network, adding to deployment complexity. This
manager node would also be a single point of failure for managing retry tasks.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;As mentioned above, two new entities would be required. No migrations would be
needed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h3&gt;Notifications &amp;amp; Audit Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;The addition of a periodic task to identify task to be retried presents an
extra load on the worker nodes (assuming they are co-located processes to the
normal worker processing, as expected). However, this process does not perform
the retry work, but rather issues tasks into the queue to then evenly
distribute back to the worker processes. Hence the additional load on a given
worker should be minimal.&lt;/p&gt;
&lt;p&gt;This proposal includes utilizing locks to deal with concurrency concerns
across the multiple worker nodes that could be handling retry tasks. This can
result in two performance impacts: (1) multiple workers might fight to grab
the lock simultaneously leading to degraded performance for the workers that
fail to grab the lock, and (2) a lock could become ‘stuck’ if a worker holding
the lock crashes.&lt;/p&gt;
&lt;p&gt;Regarding (1), locks are only utilized on the worker nodes involved in
processing asynchronous tasks which are not time sensitive. Also, the time the
lock is utilized will be very brief, just long enough to perform a query for
retry tasks and to send those tasks to queue for follow on processing. In
addition the periodic process of each worker node handles these retry tasks,
so if the deployment of worker nodes is staggered the retry processes should
not conflict. Another option is to randomly dither the periodic interval (eg.
30 seconds +- 5 seconds) so that worker nodes are less likely to conflict with
each other.&lt;/p&gt;
&lt;p&gt;Regarding concern (2) about ‘stuck’ locks, since the conditions which involve
locks are either long-running orders that can suffer delays until locks are
restored, or else are (hopefully) rare conditions when resources aren’t
available, this condition should not be critical to resolve. The proposal does
however suggest a means to remove stuck locks utilizing their created-at
times.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;The Barbican configuration file will need a configuration parameter to
periodically run the retry-query process, called ‘schedule_period_seconds’,
with a default value of 15 seconds. This parameter would be placed in a new
‘[scheduler]’ group.&lt;/p&gt;
&lt;p&gt;A configuration parameter called ‘retry_lock_timeout_seconds’ would be used to
release ‘stuck’ locks on the retry tasks table, as described in the ‘Proposed
Change’ section above. This parameter would also be added to the ‘[scheduler]’
group.&lt;/p&gt;
&lt;p&gt;A configuration parameter called ‘delay_before_update_seconds’ would be used to
configure the amount of time the SimpleCertificatePlugin delays from
initiating a demo certificate order to the time the update certificate method
is invoked. This parameter would be placed in a new ‘[simple_certificate]’
group.&lt;/p&gt;
&lt;p&gt;These configurations would be applied and utilized once the revised code base
is deployed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;john-wood-w&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Chelsea Winfree&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Add data model entities and unit tests, for OrderRetryTask and EntityLock&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add logic to SimpleCertificatePlugin per the Approach section, to allow demonstration of retry feature&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify barbican.tasks.certificate_resources.py’s _schedule_retry_task to add retry records into OrderRetryTask table&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add Oslo periodic task support&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement periodic method, that performs the query for tasks that need to be retried&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement workers sending retry RPC messages back to the queue…see note below&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add new scripts to launch the Oslo periodic task called bin/barbican-task-scheduler.py and .sh, similar to bin/barbican-keystone-listener.py and .sh&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add to the Barbican Devstack gate functional tests a test of the new retry feature via the SimpleCertificatePlugin logic added above&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add logic to handle expired locks on the OrderRetryTask table&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Note that for #6, the ‘queue’ and ‘tasks’ packages have to be modified somewhat
to allow the server logic to send messages to the queue via the client logic,
mainly to break circular dependencies. Again, see the example &lt;a class="reference external" href="https://github.com/cloudkeep/barbican/tree/verify-resource/barbican"&gt;here&lt;/a&gt;
for a working example of this server/client/retry processing.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;In addition to planned unit testing, the functional Tempest-based tests in the
Barbican repository would be augmented to add a test of the new retry feature
for the default certificate plugin.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Developer guides will need to updated, to include the additional periodic retry
process detailed above. Deployment guides will need to be updated to specify
that a new process needs to executed (for the bin/barbican-task-scheduler.sh
process).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Wed, 14 Nov 2018 00:00:00 </pubDate></item><item><title>Add Version Responses Consistent with Openstack</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/liberty/fix-version-api.html</link><description>

&lt;p&gt;Launchpad blueprint:
&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/fix-version-api"&gt;https://blueprints.launchpad.net/barbican/+spec/fix-version-api&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Barbican currently returns one-off version information for GETs to the root
resource. This blueprint calls for replacing that response with an OpenStack
consistent response based on json-home
(see &lt;a class="reference external" href="http://http://tools.ietf.org/html/draft-nottingham-json-home-03"&gt;http://http://tools.ietf.org/html/draft-nottingham-json-home-03&lt;/a&gt;),
that includes which API versions are currently supported.
Such version information could facilitate automatic discovery of services when
appended with the endpoint information retrieved from Keystone service
catalogs for example.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;When the root resource of Barbican is queried with a GET request, it should
respond with a version response consistent with other OpenStack projects,
based on json-home. This was discussed at a July 2014 mid-cycle meetup for
Keystone and Barbican
(see &lt;a class="reference external" href="https://etherpad.openstack.org/p/keystone-juno-hackathon"&gt;https://etherpad.openstack.org/p/keystone-juno-hackathon&lt;/a&gt; for details).
The following is an example of implementing a json-home type of response from
Keystone
(documented here:
&lt;a class="reference external" href="https://docs.openstack.org/api/openstack-identity-service/2.0/content/"&gt;https://docs.openstack.org/api/openstack-identity-service/2.0/content/&lt;/a&gt;Versions-d1e472.html):&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"choices"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"v1.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"DEPRECATED"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"links"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="s2"&gt;"rel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"self"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"href"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"https://identity.api.openstack.org/v1.0"&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s2"&gt;"media-types"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"values"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="s2"&gt;"base"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/xml"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/vnd.openstack.identity+xml;version=1.0"&lt;/span&gt;
                    &lt;span class="p"&gt;},&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="s2"&gt;"base"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/vnd.openstack.identity+json;version=1.0"&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"v1.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"CURRENT"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"links"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="s2"&gt;"rel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"self"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"href"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"https://identity.api.openstack.org/v1.1"&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s2"&gt;"media-types"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"values"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="s2"&gt;"base"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/xml"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/vnd.openstack.identity+xml;version=1.1"&lt;/span&gt;
                    &lt;span class="p"&gt;},&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="s2"&gt;"base"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/vnd.openstack.identity+json;version=1.1"&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"v2.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"BETA"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"links"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="s2"&gt;"rel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"self"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="s2"&gt;"href"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"https://identity.api.openstack.org/v2.0"&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="s2"&gt;"media-types"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"values"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="s2"&gt;"base"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/xml"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/vnd.openstack.identity+xml;version=2.0"&lt;/span&gt;
                    &lt;span class="p"&gt;},&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="s2"&gt;"base"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/vnd.openstack.identity+json;version=2.0"&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s2"&gt;"choices_links"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;When a GET is performed for a specific version, version details should be
provided in response such as per this Keystone example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"stable"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"updated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2014-04-17T00:00:00Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"media-types"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"base"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/vnd.openstack.identity-v2.0+json"&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"base"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/xml"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/vnd.openstack.identity-v2.0+xml"&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s2"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"v2.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"links"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"href"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://23.253.228.211:5000/v2.0/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"rel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"self"&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"href"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"https://docs.openstack.org/api/openstack-identity-service/2.0/content/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"text/html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"rel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"describedby"&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"href"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"https://docs.openstack.org/api/openstack-identity-service/2.0/identity-dev-guide-2.0.pdf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/pdf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s2"&gt;"rel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"describedby"&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;However, as Chad Lung pointed out in the Launchpad blueprint, several projects
document and implement the version responses shown above, so Barbican can
follow the same approach. Barbican only supports requests and response in the
JSON format, so XML formats will not be supported or implemented via this
blueprint.&lt;/p&gt;
&lt;p&gt;Keystone’s keystone/controllers.py implements the GET requests and builds the
version responses. Note that the MEDIA_TYPE_JSON should be
‘application/vnd.openstack.keymanagement-%s+json’. The ‘Version’ controller
defined in this file is mapped to the URI path via the keystone/routers.py
module. Finally the keystone/service.py module builds the final WSGI
application, and includes the version routers defined in routers.py.&lt;/p&gt;
&lt;p&gt;For Barbican then, the barbican/api/controllers/versions.py VersionController
class could be modified similarly to Keystone’s controllers.py, but should
be renamed to VersionsController to handle the root requests, with a new
VersionController added to return specific version detail responses.&lt;/p&gt;
&lt;p&gt;The barbican/api/app.py file should be modified to use the new
VersionsController wherever VersionController is used now. Note that while the
root version resource would support unauthenticated requests, specific version
resource requests would require authentication.&lt;/p&gt;
&lt;p&gt;Also, the build version information that is responded with the root
resource now would still need to be provided to support automated deployment
and testing processes. This blueprint proposes adding a query parameter to the
root resource such as ?build_version, that would return a JSON response similar
to the current one but without the version information, such as this:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2014.1.dev43.g22d1a96"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;An alternative to retrieving this build information is detailed in the
Alternatives section below.&lt;/p&gt;
&lt;p&gt;Finally, the Barbican Python client should be updated to take advantage of
this new version discovery information to augment the endpoint information it
retrieves from Keystone service catalogs.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Regarding utilizing existing frameworks to generate the version information,
there does not appear to be a Python library that implements json-home.&lt;/p&gt;
&lt;p&gt;Regarding the build version information, that is not addressed by the
json-home specification, although in Appendix C of the IETF reference in a
section labeled ‘Open Issues’, there appears to be a placeholder called
‘release info?’ that might address this at a future date. So perhaps we could
just add the build information to the root version response.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;The root version response will be changed from the one-off version information
returned now to the OpenStack consistent response. A specific version details
response (i.e. when performing a GET on v1/ for example) will need to be added.
The current root response that includes the build version would need to be
modified to only return this information if a query parameter is specified.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;Any processes that rely on the current build version response would need to be
modified. Clients using the Barbican Python client will need to update to the
release after the changes in this blueprint are made.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;jaosorior&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other potential contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;john-wood-w
chad-lung&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;The following CRs would build out this blueprint:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Modify version-related modules per proposal above.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;2) Implement the build_version query parameter on the root resource to return
the build version.&lt;/p&gt;
&lt;p&gt;3) Update Barbican Python client code base to query the root resource for
version information and then apply that to the endpoint information retrieved
from the Keystone service catalog.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit testing of the version resources will be added.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Update this page with API changes:
&lt;a class="reference external" href="https://github.com/cloudkeep/barbican/wiki/Application-Programming-Interface"&gt;https://github.com/cloudkeep/barbican/wiki/Application-Programming-Interface&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;See code and documentation references embedded in this blueprint above.&lt;/p&gt;
&lt;p&gt;Information about json-home is found at
&lt;a class="reference external" href="http://http://tools.ietf.org/html/draft-nottingham-json-home-03"&gt;http://http://tools.ietf.org/html/draft-nottingham-json-home-03&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Notes on the json-home discussion at the July 2014 Barbican and Keystone
mid-cycle meetup can be found at
&lt;a class="reference external" href="https://etherpad.openstack.org/p/keystone-juno-hackathon"&gt;https://etherpad.openstack.org/p/keystone-juno-hackathon&lt;/a&gt;.&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Wed, 14 Nov 2018 00:00:00 </pubDate></item><item><title>Add barbican-manage command</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/mitaka/add-barbican-manage-cmd.html</link><description>

&lt;p&gt;Blueprint:
&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/add-barbican-manage-cmd"&gt;https://blueprints.launchpad.net/barbican/+spec/add-barbican-manage-cmd&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Client Blueprint:
None&lt;/p&gt;
&lt;p&gt;A new ‘barbican-manage’ command is introduced as Barbican admin tool. This
command interacts with Barbican service for management operations which usually
cannot be accomplished with REST APIs. This can improve usability and
extensibility in the future.&lt;/p&gt;
&lt;p&gt;Other OpenStack services like Keystone &lt;a class="footnote-reference brackets" href="#id4" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; and Nova &lt;a class="footnote-reference brackets" href="#id5" id="id2" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;2&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt; also provide similar
commands for service admins.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Currently, Barbican uses individual admin commands for management functions.
For example, using barbican-db-manage for database migration, using
pkcs11-key-generation and pkcs11-kek-rewarp for HSM/pkcs11 related management,
etc. More new admin functions will be added in future releases. It’s time to
consolidate all these individual commands under a single tool for sake of
simplicity.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The syntax of new ‘barbican-manage’ command will be:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;&lt;strong&gt;barbican-manage&lt;/strong&gt; [options] &lt;em&gt;category&lt;/em&gt; &lt;em&gt;action&lt;/em&gt; [additional args]&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;em&gt;category&lt;/em&gt; and &lt;em&gt;action&lt;/em&gt; will be a list of subcommands that will be supported.
The initial implementation of &lt;strong&gt;barbican-manage&lt;/strong&gt; will be just refactoring
current command code, and unify all functions into one command.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Existing admin commands will be continue working and will be deprecated
in future according to OpenStack standard deprecation policy &lt;a class="footnote-reference brackets" href="#id6" id="id3" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;3&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Currently we have 2 categories: &lt;em&gt;db&lt;/em&gt; for database management and &lt;em&gt;hsm&lt;/em&gt; for
HSM/PKCS11 management.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;Category &lt;em&gt;db&lt;/em&gt; replaces existing &lt;strong&gt;barbican-db-manage&lt;/strong&gt; command:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;db cleanup&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Remove all soft-deleted and expired secrets from DB&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;db restore&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Restore a soft-deleted secret from DB&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;db revision&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Create a new DB version file&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;db upgrade&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Upgrade to a future version DB version&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;db history&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Show changeset history&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;db current&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Show current revision for a database&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Category &lt;em&gt;db&lt;/em&gt; can take additional argument:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;dl class="option-list"&gt;
&lt;dt&gt;&lt;kbd&gt;&lt;span class="option"&gt;--dburl&lt;/span&gt;&lt;/kbd&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;p&gt;URL to the database&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;kbd&gt;&lt;span class="option"&gt;--from-file&lt;/span&gt;&lt;/kbd&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;p&gt;Secret garbage collection configuration file&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;dl&gt;
&lt;dt&gt;Category &lt;em&gt;hsm&lt;/em&gt; replaces existing &lt;strong&gt;pkcs11-key-generation&lt;/strong&gt; and&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;strong&gt;pkcs11-kek-rewrap&lt;/strong&gt; commands:&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;tbody&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;hsm gen-mkek&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Generate HSM master key encryption key&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;hsm gen-mhmk&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Generate HSM master HMAC key&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;hsm rewrap-pkek&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;Rewrap Project KEKs after rotating to a new MKEK&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Category &lt;em&gt;hsm&lt;/em&gt; can take following additional arguments:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;dl class="option-list"&gt;
&lt;dt&gt;&lt;kbd&gt;&lt;span class="option"&gt;--library-path&lt;/span&gt;&lt;/kbd&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;p&gt;PKCS11 library path&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;kbd&gt;&lt;span class="option"&gt;--slot-id&lt;/span&gt;&lt;/kbd&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;p&gt;Slot ID&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;kbd&gt;&lt;span class="option"&gt;--passphrase&lt;/span&gt;&lt;/kbd&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;p&gt;PKCS11 login password&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;kbd&gt;&lt;span class="option"&gt;--label&lt;/span&gt;&lt;/kbd&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;p&gt;Key label&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;kbd&gt;&lt;span class="option"&gt;--length&lt;/span&gt;&lt;/kbd&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;p&gt;Key length&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;kbd&gt;&lt;span class="option"&gt;--dry-run&lt;/span&gt;&lt;/kbd&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;p&gt;Displays changes that will be made (Non-destructive)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;–dry-run requires above 5 arguments be specified&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;General ‘options’ includes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;dl class="option-list"&gt;
&lt;dt&gt;&lt;kbd&gt;&lt;span class="option"&gt;--help&lt;/span&gt;&lt;/kbd&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;p&gt;show help message&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;kbd&gt;&lt;span class="option"&gt;--version&lt;/span&gt;&lt;/kbd&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;p&gt;show command version&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;The command will read standard &lt;em&gt;barbican.conf&lt;/em&gt; to get setting for &lt;em&gt;debug&lt;/em&gt;,
&lt;em&gt;verbose&lt;/em&gt; and &lt;em&gt;log_file&lt;/em&gt; options.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;User has to have appropriate privilege to run command barbican-manage.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h3&gt;Notifications &amp;amp; Audit Impact&lt;/h3&gt;
&lt;p&gt;Event log can be generated for audit support.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="python-and-command-line-client-impact"&gt;
&lt;h3&gt;Python and Command Line Client Impact&lt;/h3&gt;
&lt;p&gt;No impact to Barbican client and OpenStack client.&lt;/p&gt;
&lt;p&gt;A new CLI admin command will be added, so its user guide need to be added.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None if existing admin commands are not used in deploying script.&lt;/p&gt;
&lt;p&gt;There is no immediate impact to deployers even if they use existing admin
commands in script for deployment. The script need to be converted to use new
&lt;em&gt;barbican-manage&lt;/em&gt; command eventually before old commands are removed according
to procedures in OpenStack standard deprecation policy.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&amp;lt;jianhua&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&amp;lt;None&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Work items or tasks&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create a new barbican-manage.py in barbican/cmd and call functions into
scripts db_manage.py and pkcs11_*.py&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add unit testcases&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add barbican-manage command script in setup.cfg&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add user guide document for barbican-manage command&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;deprecate existing command scripts. Adding deprecation warning message in
existing commands.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests will be added for all subcommands and various options.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;A new barbican-manage command user guide will be added, which should include
new user guide for database migration subcommands and user guide of
pkcs11-related subcommands modified from existing
&lt;a class="reference external" href="https://docs.openstack.org/developer/barbican/api/userguide/pkcs11keygeneration.html"&gt;https://docs.openstack.org/developer/barbican/api/userguide/pkcs11keygeneration.html&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id4" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/developer/keystone/man/keystone-manage.html"&gt;https://docs.openstack.org/developer/keystone/man/keystone-manage.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id5" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id2"&gt;2&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://docs.openstack.org/developer/nova/man/nova-manage.html"&gt;https://docs.openstack.org/developer/nova/man/nova-manage.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;aside class="footnote brackets" id="id6" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id3"&gt;3&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://governance.openstack.org/reference/tags/assert_follows-standard-deprecation.html"&gt;https://governance.openstack.org/reference/tags/assert_follows-standard-deprecation.html&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;/section&gt;
</description><pubDate>Wed, 14 Nov 2018 00:00:00 </pubDate></item><item><title>Add Certificate Generation and Management To Orders</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/juno/add-ssl-ca-support.html</link><description>

&lt;p&gt;Launchpad blueprint:
&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/add-ssl-ca-support"&gt;https://blueprints.launchpad.net/barbican/+spec/add-ssl-ca-support&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Barbican can be used to automate and streamline secure generation and storage
of SSL certificates and associated private keys from client information (such
as a CSR). This feature requires being able to coordinate between multiple
possible certificate authorities (CA) for generation, Barbican for secure
certificate storage and notification once generation is completed. This
blueprint details a plugin-based approach to satisfy these requirements.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;To generate and manage SSL certificates within Barbican via its orders
resource requires that Barbican perform these actions: (1) accept certificate
information from a client, (2) initiate a certificate generation order with
one of several possible certificate authorities (CA), (3) check on the
progress of each CA order periodically, (4) securely store certificate
information once generated by the CA, and finally (5) notify clients that the
certificate is ready to provision. This wiki page details the flows involved:
&lt;a class="reference external" href="https://wiki.openstack.org/wiki/Barbican/Blueprints/ssl-certificates"&gt;https://wiki.openstack.org/wiki/Barbican/Blueprints/ssl-certificates&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Barbican should be capable of interacting with a variety of different CAs,
each having their own custom interaction workflows. Barbican should be able to
store state on behalf of this workflow between states (such as to wait for
a CA to generate a certificate). Barbican should also provide a means for
workflow processes to reschedule calling back to the workflow process, such
as retrying a failed attempt to create a certificate order in the CA.&lt;/p&gt;
&lt;p&gt;Barbican should be capable of notifying clients about issues or generated
certificates via a variety of eventing mechanisms available to a deployment.
Examples include surfacing CADF events via Ceilometer, or issuing tickets into
a corporate ticketing system.&lt;/p&gt;
&lt;p&gt;Barbican should provide CA workflow processes the ability to securely store
certificate information in Barbican without needing to directly interact
with its datamodel.&lt;/p&gt;
&lt;p&gt;Barbican should provide CA workflow processes the ability to reschedule
themselves at a future time, perhaps to reattempt a failed process such as
establishing an order with the CA.&lt;/p&gt;
&lt;p&gt;Barbican should allow for validation of the certificate order fields prior
to initiating the CA ordering process. Barbican should allow for clients to
update information about their launched CA order, such as providing
corrections, cancellations or approvals. This interface could also support
revoking a certificate once it is created and installed in Barbican.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;This blueprint proposes using a plugin approach to interact with specific CAs.
The plugin contract will expose processing methods that represent workflow
actions, such as ‘request_certificate(…)’ or ‘check_request_status(…)’.
This blueprint will defer to implementing CRs the specific names and usages
for these methods.&lt;/p&gt;
&lt;p&gt;Because the workflow/state handling required to interact with a given CA is
expected to vary significantly between CA vendors, it is expected that the
plugin will need to manage its own state machine. However, the CA plugins
shouldn’t have to manage persisting/retrieving state machine data for a given
order instance. Hence Barbican should handle providing a dict of information
into the plugin’s methods into which they can reference their state. For
example, this might include a ‘state’ key that keeps track of the current state
machine state for an order. Barbican would then store this dict as
plugin-specific metadata about the order.&lt;/p&gt;
&lt;p&gt;A separate scheduled process run from the worker nodes (via oslo incubator’s
periodic_task feature) would poll CAs for updates to pending certificate
orders, generating RPC tasks for each update, which would eventually invoke the
CA plugin method above.&lt;/p&gt;
&lt;p&gt;Also proposed is a plugin for surfacing certificate events from Barbican.
Since CA plugins will know best within their workflows when an event should be
issued (say when a certificate is generated) the proposal is to pass the event
plugin into the CA plugin’s methods. This inversion of control (IoC) approach
would allow plugins to be in control of event sequencing, and would allow
separation from &lt;em&gt;how&lt;/em&gt; the events are handled within and from Barbican. This
plugin could have domain specific methods that make sense for certificate
processing work, such as ‘notify_certificate_is_generated()’. The default
out-of-the-box plugin would just log events. A provided optional event plugin
implementation would create CADF events for Ceilometer to handle.&lt;/p&gt;
&lt;p&gt;The CA workflow plugins also know best when to store a generated certificate.
Therefore another IoC adapter would be passed into the CA plugin’s
method providing specific methods such as ‘store_certificate()’ which would be
implemented as a Barbican Container repository save call.&lt;/p&gt;
&lt;p&gt;Finally, an IoC adapter would be passed into the CA plugin’s methods allowing
the plugin to invoke one of its method at a future time, by enqueing an RPC
call that launches the CA plugin’s method.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;The certificate generation process detailed above is a workflow that could be
expressed using a workflow framework. Several of them are discussed below.
They all generally aim to execute a series of preconfigured tasks sequentially
or in parallel until completion, potentially reverting the entire sequence if
errors occur.&lt;/p&gt;
&lt;p&gt;The certificate processing state machine does not seem to be a good fit for
this approach for two reasons:&lt;/p&gt;
&lt;p&gt;(1) Certificate processing involves potentially long delays (multiple days)
between CA interaction state machine steps, including polling the CA for
status updates or waiting for client updates. Delays and scheduled polling
behaviors do not appear to be integrated into the existing workflow approaches
below, so Barbican would need to implement such logic anyway.&lt;/p&gt;
&lt;p&gt;(2) Some state steps may need to be repeated, such as retrying initiating an
order with the CA when the CA is unavailable. So in this case, the order of
tasks executed is not known a priori, and when an error happens tasks
completed up to that point should not always be reverted.&lt;/p&gt;
&lt;p&gt;Desired though not required is that the workflow process play nicely with the
Barbican worker processes, including being able to react to RPC calls from
the queue, or to scheduled update requests.&lt;/p&gt;
&lt;p&gt;TaskFlow (&lt;a class="reference external" href="https://wiki.openstack.org/wiki/TaskFlow"&gt;https://wiki.openstack.org/wiki/TaskFlow&lt;/a&gt;) is an OpenStack Python
library that can compose tasks and workflows using Python classes. These are
intended to be run from within an ‘engine’, which manages the execution of the
configured tasks. Hence TaskFlow might be best run as a separate process or
node from the Barbican workers. It seems to be the most capable for this
blueprint’s needs, but still has the ‘fitness’ issues mentioned above.&lt;/p&gt;
&lt;p&gt;Mistral (&lt;a class="reference external" href="https://wiki.openstack.org/wiki/Mistral"&gt;https://wiki.openstack.org/wiki/Mistral&lt;/a&gt;) is an OpenStack Workflow as
a Service project. It is in an early stage however, an may not be available by
the Juno or K releases. It does not let projects upload and execute custom
code, but rather calls back to Barbican to perform its tasks.&lt;/p&gt;
&lt;p&gt;Lower level frameworks such as machinist
(&lt;a class="reference external" href="https://pypi.org/project/machinist/0.1"&gt;https://pypi.org/project/machinist/0.1&lt;/a&gt;) can operate state machines as
defined via Python objects. Like TaskFlow this might be best run as a
process separate from the Barbican workers. This framework seemed less
flexible than TaskFlow.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;The current Orders entity would need to have a new relationship added to store
a CA plugin’s metadata, similar to the key/value metadata store that was added
to the Secrets entity. This would be different than the Order’s ‘meta’
attribute, which is used to store user-provided ordering information.&lt;/p&gt;
&lt;p&gt;No database migrations should be required as the metadata is both optional and
controlled by the plugins themselves.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;The ‘certificate’ orders type is being added per another change process, so
this blueprint has not direct API impact.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;Barbican will interact with a third-party system (a certificate authority).
This interaction is only initiated by Barbican, but care must be taken to
validate both the user provided information (via the certificate plugin) as
well as the response information back from the CA.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;This blueprint calls for using a plugin approach to surface events from the
certificate generation process, in particular to notify when a certificate has
been generated and is ready to install, and when an error has occurred. Errors
could include the CA rejecting the order, is temporarily unavailable or is
rate-limiting the number of requests made by the client. In some cases,
Barbican would need to re-attempt the request at some point in the future.&lt;/p&gt;
&lt;p&gt;This blueprint will probably be the first use case for event generation and
notifications in Barbican.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;The impact of this certificate processing should be minimal, since even
though it could take days to approve and generate a certificate, the vast
majority of that time is spent waiting on either the CA to update a given
certificate order, or else for users to provide corrections or approvals.
When Barbican is processing a state machine step the computation load should
be minimal.&lt;/p&gt;
&lt;p&gt;Also, it is expected that not many certificate orders will be processed
concurrently. Even if the load does increase over time, all certificate
processing is performed asynchronously on worker nodes, so additional delays
will be accommodated and are likely to be a fraction of the overall
certificate workflow period.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None, as the current worker processes will be used.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;New facilities will be added to the current Barbican worker code base, in
particular oslo incubator’s periodic_task implementation, and the eventing
plugin.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;john-wood-w&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;alee-3
arvind-tiwari&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;The following CRs would build out this blueprint:&lt;/p&gt;
&lt;p&gt;– Add CA plugin and validation:
1) Add stevedore plugin manager for CA workflow plugin, and initial plugin
abstract interface with workflow processing methods. Default implementation
would just issue log messages. Call from the BeginOrder task for the
‘certificate’ orders type. Add initial unit testing.&lt;/p&gt;
&lt;ol class="arabic simple" start="2"&gt;
&lt;li&gt;&lt;p&gt;Add validation processing to the CA plugin.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;– Add eventing plugin:
3) Add eventing stevedore plugin manager for eventing plugin, and initial
plugin abstract interface with default logging implementation.&lt;/p&gt;
&lt;p&gt;– Add adapters:
4) Add datastore adapter and pass as IoC context to CA plugin.
5) Add task retry adapter and pass as IoC context to CA plugin.&lt;/p&gt;
&lt;p&gt;– Add orders update:
6) Modify POST order process to handle validation processing (including using
step #2 work above)
7) Add PUT handler to the ‘orders’ resource to handle client order updates.
8) Add ‘UpdateOrder’ task to asynchronously handle these updates and invoke CA
plugin methods accordingly.&lt;/p&gt;
&lt;p&gt;– Add scheduled processes:
9) Add oslo incubator’s periodic_task to worker process.
10) Add CA workflow support for periodically checking for CA status, and then
generating update events back to the Barbican worker queue.&lt;/p&gt;
&lt;p&gt;– Production plugin implementations:
11) Add CADF/Ceilometer event plugin implementation.
12) Add Symantec plugin implementation&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;The plugin restructure work associated with this blueprint should be completed
prior to implementing this work:
&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/restructure-for-plugins"&gt;https://blueprints.launchpad.net/barbican/+spec/restructure-for-plugins&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit testing of each plugin and adapter will be added. Integration testing
of at least the default plugins will be added. Symantec testing will be
needed, perhaps with a mock Symantec service.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Update &lt;a class="reference external" href="https://github.com/cloudkeep/barbican/wiki/Application-Programming-Interface"&gt;https://github.com/cloudkeep/barbican/wiki/Application-Programming-Interface&lt;/a&gt;
with API changes for the ‘certificate’ orders type, and for PUTs to orders.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;A work in progress CR with strawman code related to this blueprint is
available here: &lt;a class="reference external" href="https://review.openstack.org/#/c/95023/"&gt;https://review.openstack.org/#/c/95023/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;An analysis of the Symantec CA workflow is available here:
&lt;a class="reference external" href="https://review.openstack.org/#/c/95023/"&gt;https://review.openstack.org/#/c/95023/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Plugin design concepts related to this blueprint, including the IoC adapter
usage, are detailed here:
&lt;a class="reference external" href="https://wiki.openstack.org/wiki/Barbican/Discussion-Plugin-Design"&gt;https://wiki.openstack.org/wiki/Barbican/Discussion-Plugin-Design&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Sun, 13 May 2018 00:00:00 </pubDate></item><item><title>Add certificate to container type</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/juno/add-certificate-to-the-container-type.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/add-certificate-to-the-container-type"&gt;https://blueprints.launchpad.net/barbican/+spec/add-certificate-to-the-container-type&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Open Stack LBaaS is planning to use barbican for their certificate use case.
We need to add ‘certificate’ to the container type option.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Barbican’s Container resource is capable of storing SSL certificate along with
its private_key and passphrase. Current implementation of container only supports
RSA and Generic type, due to this limitation containers holding certificate can
not be distinguishable.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Add the &lt;cite&gt;certificate&lt;/cite&gt; option for containers. This augments the current type attribute on the containers resource and data model to accept &lt;cite&gt;certificate&lt;/cite&gt; as a valid option.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;The &lt;cite&gt;Container&lt;/cite&gt; schema will be modified to have &lt;cite&gt;certificate&lt;/cite&gt; in
the container types constraint check.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;The REST request and response structure for container may contain
&lt;cite&gt;certificate&lt;/cite&gt; in type field.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Example 01 - Container request with certificate type:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"my-cert"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"certificate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"secret_refs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"certificate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="s2"&gt;"secret_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"http://localhost:9311/v1/b885a8320e4f48c69ddffb0364eeef36/secrets/46332930-8e52-4c40-b069-cc39ca65a221"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"intermediates"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="s2"&gt;"secret_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"http://localhost:9311/v1/b885a8320e4f48c69ddffb0364eeef36/secrets/21f2234a-f65c-11e3-8791-002564955ea1"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;

       &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"private_key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="s2"&gt;"secret_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"http://localhost:9311/v1/b885a8320e4f48c69ddffb0364eeef36/secrets/094e76ed-85e0-49b1-b6ce-6bde3cf6571c"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"private_key_passphrase"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="s2"&gt;"secret_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"http://localhost:9311/v1/b885a8320e4f48c69ddffb0364eeef36/secrets/da5ccd5a-ef0f-4cb3-8d8f-dd12308b3109"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Example 02 - Container response with certificate type:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ACTIVE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"updated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2014-06-10 17:21:37.477461"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"my-cert"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"secret_refs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"secret_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:9311/v1/b885a8320e4f48c69ddffb0364eeef36/secrets/579d0ffe-a40c-47a6-b0c6-8978a441f661"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"private_key_passphrase"&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"secret_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:9311/v1/b885a8320e4f48c69ddffb0364eeef36/secrets/93688bf3-5101-47de-bdd5-46e52186038f"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"certificate"&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"intermediates"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="s2"&gt;"secret_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"http://localhost:9311/v1/b885a8320e4f48c69ddffb0364eeef36/secrets/21f2234a-f65c-11e3-8791-002564955ea1"&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;

            &lt;span class="s2"&gt;"secret_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:9311/v1/b885a8320e4f48c69ddffb0364eeef36/secrets/a7a61669-c6fb-4375-9577-11744f4a88f7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"private_key"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s2"&gt;"created"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2014-06-10 17:21:37.477448"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"container_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:9311/v1/b885a8320e4f48c69ddffb0364eeef36/containers/dc252a7d-600f-49a3-9df4-7bca35aa366d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"certificate"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h3&gt;Notifications &amp;amp; Audit Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee: atiwari (arvind-tiwari)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;CR to address data migration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CR to add certificate type in container.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;New unit test will be required to test this feature.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Documents has to be enhanced to add certificate in container type.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/cloudkeep/barbican/wiki/Application-Programming-Interface#containers-resource"&gt;https://github.com/cloudkeep/barbican/wiki/Application-Programming-Interface#containers-resource&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/add-certificate-to-the-container-type"&gt;https://blueprints.launchpad.net/barbican/+spec/add-certificate-to-the-container-type&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 08 Feb 2018 00:00:00 </pubDate></item><item><title>Adding per-secret policy to allow the storing of private secrets</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/kilo/add-creator-only-option.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/add-per-secret-policy"&gt;https://blueprints.launchpad.net/barbican/+spec/add-per-secret-policy&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;This is a companion spec to the add-per-secret-policy spec.  That spec proposed
a mechanism for allowing users outside the secrets project to access a
secret/container.  This mechanism involved storing access control data
in the database for each secret/container.&lt;/p&gt;
&lt;p&gt;This spec solves a related problem.  Currently, secrets are accessible by all
users with the relevant role in the secret creator’s project.  That means that
all members of the same project can access all secrets stored for that project.&lt;/p&gt;
&lt;p&gt;Recently there have been requests to be able to designate “private secrets”.
These are secrets that only the secret creator (the user that created the secrets)
would be able to extract.&lt;/p&gt;
&lt;p&gt;Now, it is possible to create a project for each user that would like to store
private secrets.  This seems to be a very burdensome solution, with large admin
overhead in managing all the required groups and roles.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The proposal is to store additional access data with each secret/container.  This
data (“creator_only” with a value of True/False) will be stored in the SecretACL
and ContainerACL data tables as a separate column.  The details are in the Data
Model Impact section below.&lt;/p&gt;
&lt;p&gt;When a secret/container is accessed, the creator_only information and any
whitelist information is passed up to the policy layer through target.* variables.
Access is then determined by evaluating policy rules that use these parameters.
Proposed policy rules are specified in the Policy section below.&lt;/p&gt;
&lt;p&gt;Finally, the REST API will need to be augmented to allow users to specify and
change the creator_only status of a secret/container.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="operations"&gt;
&lt;h2&gt;Operations&lt;/h2&gt;
&lt;p&gt;Many different operations are restricted when creator_only = True:&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;get:  If creator_only is true, only the secret/container’s creator will&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;be able to access the secret.  Restricting access to a container though
does NOT cascade the restriction down to the constituent secrets.&lt;/p&gt;
&lt;p&gt;Note that this does not affect whitelisted users that have explicitly been
allowed to get the secret/container.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;delete: If creator_only is true, the secret/container can only be deleted by&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;the creator.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;write:  If creator_only is true, the secret/container can only be modified by&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;the creator.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;change-acl: By default, this can only be modified by the creator.&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;list:  If creator_only is true, only the creator will be able to list the secret.&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;This means that the link to the secret will not show up if a non-creator
accesses GET /secrets&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h2&gt;Data model impact&lt;/h2&gt;
&lt;p&gt;As per the per-secret spec, secrets, containers and orders tables will have a column
added to store the creator of the secret.  This would be populated by the
creator’s user_id.&lt;/p&gt;
&lt;p&gt;A boolean column (“creator_only”) will need to be added to the ContainerACL
and SecretACL tables.  The fields for the ACL tables will be as follows:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;secret_id: foreign key to Secrets table
operation: (in this case, get, write, delete, list)
users: string, list of whitelisted users for the specified operation
creator_only: True/False&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;When a secret is designated as “creator_only”, several fields will be created/
modified:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;secret_id&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;
&lt;span class="n"&gt;secret_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;
&lt;span class="n"&gt;secret_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="n"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;
&lt;span class="n"&gt;secret_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Undesignating a secret as “creator-only” would either modify/delete the above
entries.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h2&gt;REST API impact&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A new parameter (“creator-only”), which would take the values “True” and
“False” will be added to the ACL definition.  It will default to False.
Accordingly, the ACL definition will look like:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"get"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"users"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"some_user"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="s2"&gt;"another_user"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="s2"&gt;"creator-only"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"true"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If creator-only is set to true, the fields mentioned in the section above would
be created.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;As described in the per-secret spec, the ACL could be specified as an optional
acl parameter when creating the secret with a POST request.  It can also be
retrieved or modified through a GET or POST&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;UUID&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;/&lt;/span&gt;&lt;span class="n"&gt;acl&lt;/span&gt;
&lt;span class="n"&gt;GET&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;UUID&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;/&lt;/span&gt;&lt;span class="n"&gt;acl&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="policy"&gt;
&lt;h2&gt;Policy&lt;/h2&gt;
&lt;p&gt;When a container or secret is accessed, the ACL data is retrieved from the
database and provided to the RBAC layer as target.* attributes.
For reading a secret, for example, we could pass in target.user_whitelist and
target.creator_only.&lt;/p&gt;
&lt;p&gt;The policy rule would then look something like:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;can_read_shared&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;user_in_user_whitelist&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;OR&lt;/span&gt;
&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;current_resource_permissions&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;creator_only&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;OR&lt;/span&gt; &lt;span class="n"&gt;user_is_creator&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The (current_resource_permissions) part is basically that the user has the relevant
role in the secret creator’s project.&lt;/p&gt;
&lt;p&gt;For deletes, modifications etc., the rule is much simpler because we do not
need to account for the whitelists.  Delete, for example, will likely look
something like this:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;current_resource_permissions&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;creator_only&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;OR&lt;/span&gt; &lt;span class="n"&gt;user_is_creator&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h2&gt;Alternatives&lt;/h2&gt;
&lt;p&gt;As mentioned before, for private secrets, we could create a group for each
user.  Other than being cumbersome, this will entail a maintenance load on
system administrators to keep track of new and removed users.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h2&gt;Security impact&lt;/h2&gt;
&lt;p&gt;This improves security and usability in the stack as a whole by allowing users
to specify private secrets.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h2&gt;Notifications &amp;amp; Audit Impact&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h2&gt;Other end user impact&lt;/h2&gt;
&lt;p&gt;python-barbicanclient will need to be updated to provide an interface to
populate the extra parameters.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h2&gt;Performance Impact&lt;/h2&gt;
&lt;p&gt;Accessing a secret/container will require two database calls: one to get
secret/container whitelist as part of the RBAC engine’s rules
enforcement, and one to actually get the secret.&lt;/p&gt;
&lt;p&gt;These two database accesses are logically separate as the first process is
controlled by middleware, and the second by Pecan. We might be able to utilize
the same SQLAlchemy transaction, or else cache that secret entity data for the
controllers to work with, so this might be moot.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h2&gt;Other deployer impact&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h2&gt;Developer impact&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;section id="implementation"&gt;
&lt;h3&gt;Implementation&lt;/h3&gt;
&lt;p&gt;Assignee(s)&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;alee
rm_work&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h2&gt;Work Items&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add new field to the database tables, and new parameters/calls to the REST API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add logic to parse the data and store the  data in the database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add logic to retrieve the data from the database and provide to RBAC layer as
target.* attributes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify policy rules based on these target.* attributes.  It may be necessary to
extend oslo policy here to account for the new boolean flag.  Any changes will
need to be communicated clearly to deployers as it is not guaranteed that they
will deploy with default policy files.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="dependencies"&gt;
&lt;h3&gt;Dependencies&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h3&gt;Testing&lt;/h3&gt;
&lt;p&gt;The current unit tests will also be modified to have this change reflected upon
them.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h3&gt;Documentation Impact&lt;/h3&gt;
&lt;p&gt;Barbican docs and API docs will need to be changed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h3&gt;References&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Earlier blueprint with similar ideas.
&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/secret-isolation-at-user-level"&gt;https://blueprints.launchpad.net/barbican/+spec/secret-isolation-at-user-level&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Thu, 08 Feb 2018 00:00:00 </pubDate></item><item><title>KMIP MKEK Model Plugin</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/kilo/barbican-mkek-model.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/babrican-mkek-model"&gt;https://blueprints.launchpad.net/barbican/+spec/babrican-mkek-model&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This effort aims to improve on the scalability of the existing KMIP integration
offered by Barbican. Specifically by removing possible scale limitations imposed
by the number of project secrets that can be stored in a KMIP attached HSM. We
propose adding a new plugin that implements a Master Key Encryption (MKEK) based
model. Under this model, locally stored project secrets, termed Data Encryption
Keys (DEKs), are protected by per-project Key Encryption Keys (KEKs) that are
themselves protected by the use of a Master Key Encryption Key (MKEK). This
functionality mirrors that offered by similar MKEK operations available to users
of the PKCS11 ‘p11’ plugin.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Currently, Barbican can utilise HSMs that communicate via KMIP to generate and
store key material on behalf of projects. However, several HSM appliances are
restricted by the maximum number of keys that can be stored. This maximum could
be easily exceeded in large cloud deployments.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;To combat this problem a model is presented here that stores project key
material locally within the Barbican database. This will be implemented as a
plugin following the same basic design as the PKCS11 plugin and deriving from
the CryptoPluginBase interface.&lt;/p&gt;
&lt;p&gt;To protect the local key material it is itself encrypted using a per-project Key
Encryption Key. This process is referred to as wrapping the key and a wrapped
key refers to the cipher text version of a given key value. All project key
material is wrapped using that project’s unique KEK prior to storage, and this
wrapping is performed by the attached HSM appliance. By wrapping all keys
belonging to a project with a unique KEK we gain two advantages. Firstly,
project separation is enhanced, a project acquiring another project’s wrapped
keys will be unable to utilise them. Secondly, in the event that a project’s key
material must be presented to a third party (on the issuing of a warrant or
other access demand) only that specific project’s KEK must be surrendered, other
projects remain fully protected.&lt;/p&gt;
&lt;p&gt;The KEKs belonging to various projects are themselves stored locally within the
Barbican database. To protect the KEKs from exposure should the database be
compromised, they themselves will be wrapped using a single Master Key
Encryption Key, or MKEK. No unwrapped project KEKs will be stored and this
wrapping process will again be performed by the HSM. The MKEK used is global to
the running Barbican deployment and is considered to be owned by the deployer,
rather than by any project. It is generated on the backend HSM and stored there,
the MKEK is never fetched locally into Barbican process memory as (un)wrapping
operations are performed within the HSM.&lt;/p&gt;
&lt;p&gt;The following operations are required:&lt;/p&gt;
&lt;p&gt;Key Initialisation, MKEK generation.
Initially a new MKEK will be created on the HSM and a reference will be stored
to it in the local Barbican database. Note that the MKEK itself remains on the
HSM and only its reference is stored. This logic will be placed within the
bind_kek_metadata() method, when discovering that a MKEK is not available for use
a new one will be generated.&lt;/p&gt;
&lt;p&gt;Project Initialisation, KEK generation.
A new project will be initialised by using the HSM to create a KEK for the
project. This KEK will then be retrieved, as a wrapped key using the MKEK that
resides on the HSM as a wrapping key. The wrapped KEK is stored in Barbican’s
database and the KEK will be removed from the HSM. This logic will be placed
within the bind_kek_metadata() method. Either a pre-existing KEK will be returned
or a new one will be generated if no KEK exists for the project.&lt;/p&gt;
&lt;p&gt;Project Data Encryption Key (DEK) generation.
A new key will be generated by the HSM and its reference returned to Barbican.
Barbican will then send the wrapped project KEK to the HSM as a wrapped key, and
provide its reference to the MKEK as the wrapping key so the HSM may unwrap it.
Finally, using the DEK reference, Barbican will request the newly generated DEK
be returned, wrapped by the now unwrapped KEK. This wrapped DEK is stored in the
local database and the DEK and KEK will be removed from the HSM. This logic will
be placed within the generate_symmetric() and generate_asymmetric() methods for
symmetric and asymmetric DEKs respectively.&lt;/p&gt;
&lt;p&gt;Project Data Encryption Key (DEK) storage.
Barbican will send the wrapped project KEK to the HSM as a wrapped key, and
provide its reference to the MKEK as the wrapping key so the HSM may unwrap it.
An unwrapped DEK, provided by the project, will be sent to the HSM and then
retrieved, wrapped by the projects KEK. This wrapped DEK will be stored in the
local Barbican database. The unwrapped DEK and KEK will now be removed from the
HSM. This logic will placed within the encrypt() interface method.&lt;/p&gt;
&lt;p&gt;Project Data Encryption Key (DEK) retrieval.
A project wrapped DEK (its encrypted secret) will be retrieved from Barbican’s
database by first sending the wrapped project KEK to the HSM and a reference to
the MKEK to unwrap it, this results in a reference to the unwrapped KEK.
Barbican will then send the wrapped DEK to the HSM and the reference to the
unwrapped KEK to unwrap the DEK. Finally, Barbican can now retrieve the
unwrapped DEK and return it to the requesting user. The unwrapped DEK and KEK
will now be removed from the HSM. This logic will placed within the decrypt()
interface method.&lt;/p&gt;
&lt;p&gt;Master Key Encryption Key Rotation.
The specifics of MKEK rotation and re-keying are beyond the scope of this spec
and will be tackled independently. However, information is provided here to
illustrate how this might be accomplished under the proposed model.&lt;/p&gt;
&lt;p&gt;Should it be required that the MKEK be rotated out and a new one created, then
this might be accomplish as follows. Firstly a new MKEK is generated on the HSM
and its reference retrieved and stored as the active MKEK version, termed
‘originator-usage’. When a new project KEK must be created, the MKEK currently
operating in originator-usage will be used for wrapping and its reference stored
alongside the wrapped KEK as meta data. This MKEK reference data will allow
Barbican to indicate the correct master key to be used during unwrapping. Former
MKEKs are maintained in the HSM for retrieval of data only, termed
‘recipient-usage’. In this way new KEKs are protected by the new MKEK and older
ones remain viable by referencing the earlier MKEKs stored in the HSM.&lt;/p&gt;
&lt;p&gt;After a recipient-usage MKEK reaches a defined age, all KEKs wrapped by it
should be re-keyed, that is unwrapped and then re-wrapped, using the
originator-usage key. The period of time that an MKEK may remain valid for
recipient-usage is termed the crypto-period and is defined via a config setting.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;An existing plugin, the KMIPSecretStore is already available to Barbican and can
be considered as an alternative to the MKEK model. It uses KMIP to communicate
with a backend HSM and stores all key material within the HSM itself. As such
it is limited by the HSMs own storage capacity.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;No changes to the data model are required. All needed data can be stored as
plugin specific meta-data. The wrapped per-project KEK will be stored, along
with a reference to the MKEK in the kek_meta_dto object. If some form of key
rotation is in effect (again, the specific details of key rotation are beyond
the scope of this spec) then MKEK version info will be stored in the per-secret
kek_extended_meta_dto object.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;No changes need to be made to the REST API.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;This change uses encryption on the HSM to protect key material, however it
introduces no additional security concerns over the existing KMIPSecretStore
plugin. Project DEKs are stored in the local database but they are protected
by the project KEK. The project KEK is store in the local database and this
is protected by the MKEK. The MKEK is never stored or used outside of the HSM.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h3&gt;Notifications &amp;amp; Audit Impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;N/A&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;This change will incur a performance impact through additional communication to
the backend HSM. These communications will need to be protected through the use
of a TLS secured link. Additionally operations at scale will be limited to how
rapidly the HSM can (un)wrap and return key material. Generally this is a fast
operation but will be subject to network latency communicating to the HSM.&lt;/p&gt;
&lt;p&gt;We expect this overhead to be exaggerated initially owing to the use of simple
atomic KMIP operations. Once more complex compound operations are supported by
the underlying library this situation will be improved.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;No additional deployment impact is created by this proposed change over that
required by the KMIPSecretStore. That is, a backend HSM that can communicate via
KMIP must be available and contactable for successful operation.&lt;/p&gt;
&lt;p&gt;Note also that although the plugin contract remains the same as the existing
KMIPSecretStore plugin, the semantics of the stored data are incompatible.
Since this is a new plugin rather than a modification to the existing KMIP
plugin it is believed that no data versioning should be required since data
generated by the respective plugins should be considered entirely incompatible.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;N/A the plugin is self contained.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;tim-kelsey &amp;lt;tkelsey&amp;gt;
rob-clark &amp;lt;hyakuhei&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create spec (this spec).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write the plugin and tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Confirm all Barbican tests, new and old, still pass.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Review the code.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;This will require no new dependencies over KMIPSecretStore, that is it will
require PyKMIP library v0.2 or greater.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;A suite of unit tests will be produced to test the new code. In order to test
the plugin functionality fully a KMIP capable HSM will need to be available to
gate tests.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;No changes to documented APIs will be needed. New plugin specific configuration
options will be created, and these should be documented.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Option&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Meaning&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;mkek_crypto_plugin.crt_file_path&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;KMIP client certificate file path.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;mkek_crypto_plugin.key_file_path&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;KMIP client key file.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;mkek_crypto_plugin.key_password&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;KMIP client key password.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;mkek_crypto_plugin.user_name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;KMIP user name.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;mkek_crypto_plugin.user_pass&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;KMIP user password.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;mkek_crypto_plugin.hsm_host&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;HSM host IPs, comma separated.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;mkek_crypto_plugin.hsm_port&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;HSM port number.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;Please refer to KMIPSecretStore plugin documentation.
Please refer to the PKCS11 plugin MKEK implementation.
Please refer to the previously merged spec for PKCS11 that solves a similar
problem:
&lt;a class="reference external" href="https://review.openstack.org/#/c/107775/4/specs/juno/restructure-pkcs11-plugin.rst"&gt;https://review.openstack.org/#/c/107775/4/specs/juno/restructure-pkcs11-plugin.rst&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The KMIP specification can be found at:
&lt;a class="reference external" href="http://docs.oasis-open.org/kmip/spec/v1.2/kmip-spec-v1.2.html"&gt;http://docs.oasis-open.org/kmip/spec/v1.2/kmip-spec-v1.2.html&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 08 Feb 2018 00:00:00 </pubDate></item><item><title>Rolling Upgrade</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/pike/rolling-upgrade.html</link><description>

&lt;p&gt;Barbican users would like to upgrade their existing environments with minimal downtime.
This spec outlines the changes required to be able to assert the various upgrade tags.
The goal for Pike is to assert &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;assert:supports-rolling-upgrade&lt;/span&gt;&lt;/code&gt; tag.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description:&lt;/h2&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;There are currently six upgrade tags:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;assert:follows-standard-deprecation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;assert:supports-upgrade&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;assert:supports-accessible-upgrade&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;assert:supports-rolling-upgrade&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;assert:supports-zero-downtime-upgrade&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;assert:supports-zero-impact-upgrade&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Status tags in Barbican project:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;assert:follows-standard-deprecation: Done [1]&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;assert:supports-upgrade: Done [2]&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;assert:supports-accessible-upgrade: Not yet [3]&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;assert:supports-rolling-upgrade: Not yet [4]&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;assert:supports-zero-downtime-upgrade: Not yet [5]&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;assert:supports-zero-impact-upgrade: Not yet [6]&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change:&lt;/h2&gt;
&lt;p&gt;To support rolling upgrade for Barbican, we need to compare feature lists
support for upgrade and rolling upgrade as follows:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Maintenance Mode&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Live Migration&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Upgrade Orchestration&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Multi-version Interoperability&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Online Schema Migration&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Graceful Shutdown&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Upgrade Orchestration - Remove&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Upgrade Orchestration - Tooling&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Upgrade Gating&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Project Tagging&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For Barbican, upgrading from release N-1 to release N then to N+1,
we are following supporting status and performing detail items as follows:
&lt;a class="reference external" href="https://github.com/openstack/development-proposals/blob/master/development-proposals/proposed/rolling-upgrades.rst"&gt;https://github.com/openstack/development-proposals/blob/master/development-proposals/proposed/rolling-upgrades.rst&lt;/a&gt;&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Maintenance Mode: No need to implemented&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;No need to implement it because of plugin mechanisms and no
scheduler/placement services&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;ol class="arabic simple" start="2"&gt;
&lt;li&gt;&lt;p&gt;Live Migration: No need to implemented&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Because Barbican does not have data plane. All information will be stored
in its database and secret store plugins.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;ol class="arabic simple" start="3"&gt;
&lt;li&gt;&lt;p&gt;Upgrade Orchestration: Not yet implemented&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Multi-version interoperability&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;API microversion: Not yet - Barbican does not need microversions for
rolling upgrade.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;RPC versioning: Not yet implemented.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;RPC object version (Oslo.VersionedObjects): Not yet implemented.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;ol class="arabic simple" start="5"&gt;
&lt;li&gt;&lt;p&gt;Online Schema Migration: Not yet implemented&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Graceful Shutdown: Implemented&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Barbican-api is using Pecan to expose API and Pecan has supported graceful
shutdown so it means barbican-api has supported this feature as well&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other services in Barbican are using oslo.service to launch the services
and oslo.service has implemented graceful shutdown so they have supported
this feature also.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;ol class="arabic simple" start="7"&gt;
&lt;li&gt;&lt;p&gt;Upgrade Orchestration: Not yet implemented&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Upgrade Orchestration: Tooling implemented&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Upgrade Gating: Implemented&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Project Tagging: Not yet implemented&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Assert the tag and notify the OpenStack Technical Committee&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Impacted because the O.VO codebase will change the way Barbican services
communicate to database as well as the data flow between Barbican internal
services.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;End users will have minimal downtime when upgrading barbican
services.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;It is anticipated that a rolling upgrade will require the operators
intervention.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Developers will need to be aware of Barbican features that enable rolling
upgrades and make sure they are not removed (Developers will also need to work
within the constraints of the database strategy for rolling upgrades, but that
developer impact is covered by another spec).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h3&gt;Implementation&lt;/h3&gt;
&lt;/section&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Primary assignee:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;namnh&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Other contributors:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;daidv&lt;/p&gt;
&lt;p&gt;hieulq&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Apply O.VO in Barbican before rolling upgrade:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add oslo.versionedobjects to requirements docs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement barbican O.VO base objects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Migrate current database object to OVO objects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement extra fields in objects/fields.py.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement RPC object registry and register all objects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement and attach the object serializer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement the indirection API(VersionedObjectIndirectionAPI)
in the objects/base.py&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement Unit Test for Barbican O.VO module.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Perform rolling upgrade for O.VO.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Providing serialized versions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement a new method to check version.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement RPC pinning version.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement methods to communicating with DB, such as query, save and create.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Perform rolling upgrade for OSM along with O.VO which completed before.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implementing DB upgrade mechanism for Barbican to perform
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;barbican-db-manage&lt;/span&gt;&lt;/code&gt; command via CLI including three branches:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;‘–expand’ branch: To add columns, tables or triggers in barbican
database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;‘–contract’ branch: to delete columns, tables or trigger after all
services in branch are upgraded to new release.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Perform data gradually migrate to new schema.
by multi-version interoperability (included O.VO and RPC Pinning).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ensure all data have migrated to new schema via online_data_migrations
commandline.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write documentation for rolling upgrade (operator docs).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assert the tag and notify the OpenStack Technical Committee.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h3&gt;References&lt;/h3&gt;
&lt;p&gt;[1] &lt;a class="reference external" href="https://governance.openstack.org/tc/reference/tags/assert_follows-standard-deprecation.html#tag-assert-follows-standard-deprecation"&gt;https://governance.openstack.org/tc/reference/tags/assert_follows-standard-deprecation.html#tag-assert-follows-standard-deprecation&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[2] &lt;a class="reference external" href="https://governance.openstack.org/tc/reference/tags/assert_supports-upgrade.html#application-to-current-projects"&gt;https://governance.openstack.org/tc/reference/tags/assert_supports-upgrade.html#application-to-current-projects&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[3] &lt;a class="reference external" href="https://governance.openstack.org/tc/reference/tags/assert_supports-accessible-upgrade.html"&gt;https://governance.openstack.org/tc/reference/tags/assert_supports-accessible-upgrade.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[4] &lt;a class="reference external" href="https://governance.openstack.org/tc/reference/tags/assert_supports-rolling-upgrade.html"&gt;https://governance.openstack.org/tc/reference/tags/assert_supports-rolling-upgrade.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[5] &lt;a class="reference external" href="https://governance.openstack.org/tc/reference/tags/assert_supports-zero-downtime-upgrade.html"&gt;https://governance.openstack.org/tc/reference/tags/assert_supports-zero-downtime-upgrade.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[6] &lt;a class="reference external" href="https://governance.openstack.org/tc/reference/tags/assert_supports-zero-impact-upgrade.html"&gt;https://governance.openstack.org/tc/reference/tags/assert_supports-zero-impact-upgrade.html&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
</description><pubDate>Sat, 10 Jun 2017 00:00:00 </pubDate></item><item><title>Multiple Secret Backend Support</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/newton/multiple-secret-backend.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/multiple-secret-backend"&gt;https://blueprints.launchpad.net/barbican/+spec/multiple-secret-backend&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Barbican provides capability to create and store secrets via its plugin
mechanism. Barbican has KMIP, PKCS11 and Dogtag KRA plugins for creating and
managing secrets in HSM (Hardware Security Module) devices and &lt;cite&gt;store_crypto&lt;/cite&gt;
plugin for storing secrets in its own database. Enterprises generally have HSM
devices to safely secure their key material (data-at-rest) and to meet
compliance requirements.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Barbican supports secret storage in HSM device as well as in a database. So far,
Barbican has implicit concept of configuring one active plugin for secret store
which means all of the new secrets are going to be stored via same plugin (i.e.
same storage backend). This approach can limit the usage of barbican in a cloud
deployment where not all services/applications have similar data sensitivity
and hence don’t have necessity of using same mechanism to safeguard their key
material. Also HSM are expensive devices which have limited storage capacity
and performance characteristics in comparison to database. Current one active
secret store plugin approach is inflexible for following use cases.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;In a deployment, a deployer may be okay storing their dev/test resources
using a low-security secret store, such as one backend by software-only
crypto, but may want to use an HSM-backed secret store for production
resources.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In a deployment, for certain use cases where a client requires high
concurrent access of stored keys, HSM might not be a good storage backend.
Also scaling them horizontally to provide higher scalability is a costly
approach with respect to database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;HSM devices generally have limited storage capacity so a deployment will
have to watch its stored keys size proactively to remain under the limit
constraint. This is applicable in KMIP backend more than with PKCS11 backend
because of plugin’s different storage approach. This aspect can also result
from above use case scenario where deployment is storing non-sensitive (from
dev/test environment) encryption keys in HSM.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Barbican running as IaaS service or platform component where some class of
client services have strict compliance requirements (e.g. FIPS) so will use
HSM backed plugins whereas others may be okay storing keys in software-only
crypto plugin.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Currently there is no simple solution to support above use-cases. The suggestion
of asking deployment to have a separate barbican endpoint per plugin is not a
good usage experience. See &lt;a class="reference internal" href="#alternatives-label"&gt;&lt;span class="std std-ref"&gt;Alternatives&lt;/span&gt;&lt;/a&gt; section for further
details. As there is only one secret store backend available, so client (or
class of services) does not have choice to choose backend regardless of its
requirement related to safeguarding those keys.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Proposal is to allow multiple secret store backends available in a single
barbican deployment. As part of this change, client will have the choice to
select preferred backend at a project level.&lt;/p&gt;
&lt;p&gt;For this, a Barbican deployment will have at least 2 secret storage backend
enabled and need to specify one backend to be a deployment level (global)
default option. Project administrators will have choice of pre-selecting one
backend as the preferred choice for secrets created under that project. Any
&lt;strong&gt;new&lt;/strong&gt; secret created under that project will use the preferred backend to
store its key material. When there is no project level storage backend
selected, then new secret will use the global secret storage backend.&lt;/p&gt;
&lt;p&gt;As each secret already has metadata which captures its backend information,
Barbican can allow clients to specify a specific storage backend when creating
or storing new secret in Barbican. This can be a future enhancement if there is
an actual use case for this requirement. Currently this feature is not in scope
of this effort.&lt;/p&gt;
&lt;p&gt;Also to manage this feature, a flag &lt;cite&gt;enable_multiple_secret_stores&lt;/cite&gt; will be
added. By default, this flag will be disabled (set as false). So any existing
logic changes need to account for that flag value and modify only when this
flag is enabled. When barbican is started with this flag enabled, then need to
make sure that global default plugin exists in config file.&lt;/p&gt;
&lt;section id="change-in-new-secret-generate-and-storage"&gt;
&lt;h3&gt;Change in New Secret Generate and Storage&lt;/h3&gt;
&lt;p&gt;Currently a secret store plugin expose its generate and store capability via its
&lt;cite&gt;supports&lt;/cite&gt; API mechanism. This mechanism checks that input secret specification
(algorithm, length) is supported by plugin backend.&lt;/p&gt;
&lt;p&gt;When a project has defined its preferred secret store plugin, then &lt;strong&gt;only&lt;/strong&gt; that
plugin is checked for supports criteria. If preferred plugin does not meets the
given input criteria, then 400 error with related message is returned to the
client. For this to happen, &lt;cite&gt;get_active_plugins&lt;/cite&gt; logic will return project
level preferred plugin if defined otherwise global default plugin.&lt;/p&gt;
&lt;p&gt;This logic of preferred secret generate and store needs to be applied on order
processing side as well. Synchronous or asynchronous order processing logic
needs to be modified so that when generate plugin is looked up for new secret,
it provides project level preferred plugin and then global default plugin. Same
goes for secret store logic needed for symmetric key storage and certificate
storage after certificate are generated successfully during order processing.&lt;/p&gt;
&lt;p&gt;Barbican has key wrapping support (in few plugins) to ensure that secret is
pre-encrypted in such a way that only client and backend store can decrypt the
secret. For this client needs to have access to transport key to pre-encrypt
while storing or reading that secret back. With multiple backend support,
reading of transport key will not be impacted. For existing secrets, client
invokes secret metadata API which returns secret transport key id in response
when requested. This id is derived from secret plugin association and plugin
transport key association. For new secrets, if there is project level preferred
backend specified, then returned transport key is specific to that backend. If
project does not have project preferred backend, then it will return transport
key specific to global default backend. This way, there should not be case
where transport key and secret store backends are different.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;span id="alternatives-label"/&gt;&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;One alternative suggested earlier has been to deploy separate Barbican servers
to have different endpoints for each supported plugin. This may work though it
is not a good usage experience from client perspective. Now onus is on the
client to maintain different barbican endpoints in their configuration and to
remember on their side which secrets is accessed via which endpoint. Also some
of current service integrations generally has support for one barbican endpoint
so this may not be feasible for existing service integrations. Then there is
standard issue of managing these endpoints in keystone service catalog.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="service-configuration-impact"&gt;
&lt;h3&gt;Service Configuration impact&lt;/h3&gt;
&lt;p&gt;To support multiple plugin configuration, following configuration format is
needed as current multiple plugin configuration does not define a clear
relationship between secret store and crypto plugin:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;secretstore&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;enable_multiple_secret_stores&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;
&lt;span class="n"&gt;stores_lookup_suffix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;software&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;kmip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pkcs11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dogtag&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;secretstore&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;software&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;secret_store_plugin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;store_crypto&lt;/span&gt;
&lt;span class="n"&gt;crypto_plugin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;simple_crypto&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;secretstore&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;kmip&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;secret_store_plugin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;kmip_plugin&lt;/span&gt;
&lt;span class="n"&gt;global_default&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;secretstore&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;dogtag&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;secret_store_plugin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dogtag_plugin&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;secretstore&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;pkcs11&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;secret_store_plugin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;store_crypto&lt;/span&gt;
&lt;span class="n"&gt;crypto_plugin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p11_crypto&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;When multiple secret stores support is enabled, then this new list property
&lt;cite&gt;stores_lookup_suffix&lt;/cite&gt; is going to be used for looking up relevant supported
plugin names in oslo configuration section constructed using pattern
‘secretstore:{suffix}’. One of the plugin must be explicitly identified as
&lt;cite&gt;global_default = True&lt;/cite&gt;. There is going be a validation around this
requirement. Ordering of suffix does not matter.&lt;/p&gt;
&lt;p&gt;When multiple secret stores are enabled, then property
&lt;cite&gt;enabled_secretstore_plugins&lt;/cite&gt; and &lt;cite&gt;enabled_crypto_plugins&lt;/cite&gt; are not used for
instantiating supported plugins. Instead above mentioned mechanism is used to
instantiate store and cryto plugins.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;A new table, &lt;strong&gt;secret_stores&lt;/strong&gt;, is going to be created for storing secret store
backend information. At barbican application startup, this table is going to
add new entry for plugins supported, if not present, based on
&lt;cite&gt;secret_store_plugin&lt;/cite&gt; and &lt;cite&gt;crypto_plugin&lt;/cite&gt; combination. One of secret store
plugin entry in db will have &lt;cite&gt;global_default&lt;/cite&gt; column value as true.:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;table_exists&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dialect&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;has_table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'secret_stores'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;table_exists&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
   &lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
         &lt;span class="s1"&gt;'secret_stores'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
         &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'created_at'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
         &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'updated_at'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
         &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'deleted_at'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
         &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'deleted'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
         &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'status'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
         &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'store_plugin'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
         &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'crypto_plugin'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
         &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'global_default'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
         &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
         &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PrimaryKeyConstraint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
         &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UniqueConstraint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'store_plugin'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'crypto_plugin'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                             &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'_secret_stores_plugin_names_uc'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
         &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UniqueConstraint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                             &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'_secret_stores_name_uc'&lt;/span&gt;
   &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;At service startup, logic is going to be added to populate secret_stores data.
See &lt;a class="reference internal" href="#global-default-api-label"&gt;&lt;span class="std std-ref"&gt;Getting Global Default Backend&lt;/span&gt;&lt;/a&gt; for API. This new table is going to have
crypto_plugin field to account for software-only and PKCS11 plugin case. Both
plugins use &lt;cite&gt;store_crypto&lt;/cite&gt; as secret store backend and difference is in crypto
plugin name i.e. &lt;cite&gt;simple_crypto&lt;/cite&gt; vs. &lt;cite&gt;p11_crypto&lt;/cite&gt; plugin.&lt;/p&gt;
&lt;p&gt;Each secret store and crypto plugins implementation going to have new config
‘plugin_name’ added in their plugin specific configuration. This name is
intended to be user friendly name and we will add default for it which can be
updated via config if needed. This plugin name is going to be used when
creating new secret store entry. For PKCS11 and DB backend, crypto plugin names
are going to be used in &lt;cite&gt;name&lt;/cite&gt; field as they do not directly extend secret
store base classes.&lt;/p&gt;
&lt;p&gt;Another new table, &lt;strong&gt;project_secret_stores&lt;/strong&gt;, is going to be created for storing
per project secret store linking data.:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;table_exists&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dialect&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;has_table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'project_secret_stores'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;table_exists&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
   &lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
         &lt;span class="s1"&gt;'project_secret_stores'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
         &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'created_at'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
         &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'updated_at'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
         &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'deleted_at'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
         &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'deleted'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
         &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'status'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
         &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'secret_store_id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
         &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'project_id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
         &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PrimaryKeyConstraint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
         &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ForeignKeyConstraint&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'secret_store_id'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'secret_stores.id'&lt;/span&gt;&lt;span class="p"&gt;],),&lt;/span&gt;
         &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ForeignKeyConstraint&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'project_id'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'projects.id'&lt;/span&gt;&lt;span class="p"&gt;],),&lt;/span&gt;
         &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UniqueConstraint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'secret_store_id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                             &lt;span class="s1"&gt;'project_id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                             &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'_project_secret_stores_id_project_uc'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ix_project_secret_stores_store_id'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s1"&gt;'project_secret_stores'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'secret_store_id'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;unique&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ix_project_secret_stores_project_id'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s1"&gt;'project_secret_stores'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'project_id'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;unique&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This table is going to be populated whenever a project level preferred store is
set. In case of update of existing project preferred value, existing entry will
be removed and new entry is going to be created.&lt;/p&gt;
&lt;p&gt;There is no database migration needed as its a new feature.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;There is no impact on &lt;em&gt;existing&lt;/em&gt; barbican API(s). Following new REST API are
going to be added to support this new feature.&lt;/p&gt;
&lt;p&gt;In case multiple secret store backend is not enabled and response is not
applicable ( &lt;cite&gt;/secret-stores/{ID}/preferred&lt;/cite&gt; ), secret-stores related API will
result in error 404.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="listing-all-secret-store-backend"&gt;
&lt;h3&gt;Listing All Secret Store Backend&lt;/h3&gt;
&lt;p&gt;A new API resource tree &lt;cite&gt;/secret-stores&lt;/cite&gt; is going to be added for managing
available secret storage backends. This API will provide list of available
secret store backends. Only project administrator (users with admin role) are
authorized to invoke this API.&lt;/p&gt;
&lt;p&gt;REST API: GET /secret-stores:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
   &lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;stores&lt;/span&gt;
   &lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'f9cf2d480ba3485f85bdb9d07a4959f1'&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
   &lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;

   &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"secret-stores"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;
         &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"PKCS11 HSM"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"global_default"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"secret_store_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:9311/v1/secret-stores/4d27b7a7-b82f-491d-88c0-746bd67dadc8"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"store_plugin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"store_crypto"&lt;/span&gt;
            &lt;span class="s2"&gt;"crypto_plugin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"p11_crypto"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"secret_store_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"4d27b7a7-b82f-491d-88c0-746bd67dadc8"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ACTIVE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"created"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2016-08-22T23:46:45.114283"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"updated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2016-08-22T23:46:45.114283"&lt;/span&gt;
         &lt;span class="p"&gt;},&lt;/span&gt;
         &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"KMIP HSM"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"global_default"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"secret_store_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:9311/v1/secret-stores/93869b0f-60eb-4830-adb9-e2f7154a080b"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"store_plugin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"kmip_plugin"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"crypto_plugin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"secret_store_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"93869b0f-60eb-4830-adb9-e2f7154a080b"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ACTIVE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"created"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2016-08-22T23:46:45.124554"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"updated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2016-08-22T23:46:45.124554"&lt;/span&gt;
         &lt;span class="p"&gt;},&lt;/span&gt;
         &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Software Only Crypto"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"global_default"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"secret_store_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:9311/v1/secret-stores/0da45858-9420-42fe-a269-011f5f35deaa"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"store_plugin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"kmip_plugin"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"crypto_plugin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"simple_crypto"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"secret_store_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"0da45858-9420-42fe-a269-011f5f35deaa"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ACTIVE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"created"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2016-08-22T23:46:45.127866"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"updated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2016-08-22T23:46:45.127866"&lt;/span&gt;
         &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="reading-a-secret-store-backend"&gt;
&lt;h3&gt;Reading A Secret Store Backend&lt;/h3&gt;
&lt;p&gt;Any barbican user can invoke a given secret store backend info. Returned name is
derived from friendly plugin name defined in service configuration. Each secret
store plugin and crpyto plugins have default name which can be overriden in
&lt;cite&gt;plugin_name&lt;/cite&gt; under that plugin section. Only project administrator (users with
admin role) are authorized to invoke this API.&lt;/p&gt;
&lt;p&gt;REST API: GET /secret-stores/{secret_store_id}:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
   &lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;stores&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;d27b7a7&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;b82f&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;491&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;88&lt;/span&gt;&lt;span class="n"&gt;c0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;746&lt;/span&gt;&lt;span class="n"&gt;bd67dadc8&lt;/span&gt;
   &lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'f9cf2d480ba3485f85bdb9d07a4959f1'&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
   &lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;

   &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"PKCS11 HSM"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"global_default"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"secret_store_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:9311/v1/secret-stores/4d27b7a7-b82f-491d-88c0-746bd67dadc8"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"store_plugin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"store_crypto"&lt;/span&gt;
      &lt;span class="s2"&gt;"crypto_plugin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"p11_crypto"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"secret_store_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"4d27b7a7-b82f-491d-88c0-746bd67dadc8"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ACTIVE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"created"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2016-08-22T23:46:45.114283"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"updated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2016-08-22T23:46:45.114283"&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="preferred-secret-store-backend"&gt;
&lt;h3&gt;Preferred Secret Store Backend&lt;/h3&gt;
&lt;p&gt;Project administrator (users with admin role) can add, update or remove
preferred secret store backend for their project. Project information is
derived from project scoped token. In a barbican deployment without keystone
setup, project information is obtained from &lt;cite&gt;X-Project-Id&lt;/cite&gt; request header.&lt;/p&gt;
&lt;section id="getting-per-project-secret-store-backend"&gt;
&lt;h4&gt;Getting Per Project Secret Store Backend&lt;/h4&gt;
&lt;p&gt;Only project administrator can request a reference to the preferred secret store
if assigned previously. When a preferred secret store is set for a project,
then new project secrets are stored using that store backend. If multiple
secret store support is not enabled, then this resource will return 404 (Not
Found title) error.&lt;/p&gt;
&lt;p&gt;REST API:  GET /v1/secret-stores/preferred:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;stores&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;preferred&lt;/span&gt;
&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
   &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"f9cf2d480ba3485f85bdb9d07a4959f1"&lt;/span&gt;
   &lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;Ok&lt;/span&gt;
&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"KMIP HSM"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s2"&gt;"global_default"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s2"&gt;"secret_store_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:9311/v1/secret-stores/93869b0f-60eb-4830-adb9-e2f7154a080b"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s2"&gt;"store_plugin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"kmip_plugin"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s2"&gt;"crypto_plugin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s2"&gt;"secret_store_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"93869b0f-60eb-4830-adb9-e2f7154a080b"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ACTIVE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s2"&gt;"created"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2016-08-22T23:46:45.124554"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s2"&gt;"updated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2016-08-22T23:46:45.124554"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="setting-per-project-secret-store-backend"&gt;
&lt;h4&gt;Setting Per Project Secret Store Backend&lt;/h4&gt;
&lt;p&gt;Only project administrator can set the per project backend. This API will set or
update the per project backend for any new secrets created after that change.&lt;/p&gt;
&lt;p&gt;REST API: POST /secret-stores/{secret_store_id}/preferred:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;stores&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;7776&lt;/span&gt;&lt;span class="n"&gt;adb8&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;e865&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;413&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="n"&gt;ccc&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;f09c3fe0213&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;preferred&lt;/span&gt;
&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
   &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'2f30ca66d27d4d0cbff51d44bc5ac66e'&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="mi"&gt;204&lt;/span&gt; &lt;span class="n"&gt;No&lt;/span&gt; &lt;span class="n"&gt;Content&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="deleting-per-project-secret-store-backend"&gt;
&lt;h4&gt;Deleting Per Project Secret Store Backend&lt;/h4&gt;
&lt;p&gt;Only project administrator can remove the per project backend.&lt;/p&gt;
&lt;p&gt;REST API: DELETE /secret-stores/{secret_store_id}/preferred:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;span class="n"&gt;DELETE&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;stores&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;7776&lt;/span&gt;&lt;span class="n"&gt;adb8&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;e865&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;413&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="n"&gt;ccc&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;f09c3fe0213&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;preferred&lt;/span&gt;
&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
   &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'2f30ca66d27d4d0cbff51d44bc5ac66e'&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="mi"&gt;204&lt;/span&gt; &lt;span class="n"&gt;No&lt;/span&gt; &lt;span class="n"&gt;Content&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="global-default-secret-store-backend"&gt;
&lt;h3&gt;Global Default Secret Store Backend&lt;/h3&gt;
&lt;p&gt;Global default secret store is used when a project in barbican does not have a
preferred secret store setting. In that case, new secrets created under that
project will use global secret store to generate and store keys.&lt;/p&gt;
&lt;p&gt;Global default secret store value is not expected to change that frequently so
its value is managed via service configuration. At service startup,
global_default value must be explicitly set in one of plugin related
configuration section.&lt;/p&gt;
&lt;p&gt;Changing global default secret store plugin in configuration should not impact
project (without preferred plugin) &lt;em&gt;existing&lt;/em&gt; secrets as those secrets metadata
in db already has information about its associated plugin backend.&lt;/p&gt;
&lt;section id="getting-global-default-backend"&gt;
&lt;span id="global-default-api-label"/&gt;&lt;h4&gt;Getting Global Default Backend&lt;/h4&gt;
&lt;p&gt;Only project administrator can read the current global default backend value.&lt;/p&gt;
&lt;p&gt;REST API: GET /secret-stores/global-default:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;stores&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="k"&gt;global&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;
&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
   &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'2f30ca66d27d4d0cbff51d44bc5ac66e'&lt;/span&gt;
   &lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'application/json'&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;Ok&lt;/span&gt;
&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"PKCS11 HSM"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s2"&gt;"global_default"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s2"&gt;"secret_store_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:9311/v1/secret-stores/4d27b7a7-b82f-491d-88c0-746bd67dadc8"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s2"&gt;"store_plugin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"store_crypto"&lt;/span&gt;
   &lt;span class="s2"&gt;"crypto_plugin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"p11_crypto"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s2"&gt;"secret_store_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"4d27b7a7-b82f-491d-88c0-746bd67dadc8"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ACTIVE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s2"&gt;"created"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2016-08-22T23:46:45.114283"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s2"&gt;"updated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2016-08-22T23:46:45.114283"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Operation &lt;cite&gt;POST&lt;/cite&gt; or &lt;cite&gt;DELETE&lt;/cite&gt; on &lt;cite&gt;/secret-stores/global-default&lt;/cite&gt; is not allowed.
So invoking that resource should generate 405 (Method Not Allowed) error.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;No impact as these are new APIs. Some of new APIs will require service
administrator privileges to make changes. As result of this change, deployments
will have choice to use database as secret store backend for some secrets.
Database backend is considered less secure backend with reference to HSM
storage option. But this feature in itself does not introduce a security risk
as database backend is barbican existing backend and deployer can choose not to
use it.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h3&gt;Notifications &amp;amp; Audit Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="python-and-command-line-client-impact"&gt;
&lt;h3&gt;Python and Command Line Client Impact&lt;/h3&gt;
&lt;p&gt;These new APIs need to be supported in barbican client API and CLI (command line
interface).&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;There should not be impact on existing deployment as its a new feature. By
default, this feature will be disabled. Once this feature is enabled, clients
will have choice to define and use specific backend for a project. To use this,
clients will initially have to use new APIs to set their project level
preferred secret store plugins.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Minimal. On API usage level, this is expected to be infrequent admin operation.
Impact related to creating new secret and storing secret flow will be also very
minimal.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;This new feature is going to be disabled by default. There is new flag added to
enable i.e. &lt;cite&gt;enable_multiple_secret_stores&lt;/cite&gt; in &lt;cite&gt;secretstore&lt;/cite&gt; section of
barbican configuration. Also for multiple plugins support, deployer will need
to define supported plugins configuration as mentioned above (different from way
currently supported).&lt;/p&gt;
&lt;p&gt;There is no migration needed and deployment should work with default
configuration as-is.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;There should not be any impact on plugin developers and existing API.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;arunkant&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Other contributors:&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add documentation for secret stores API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add model layer changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Logic to populate secret_stores table data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add logic to parse multiple plugin configuration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add controller layer changes for new api.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify secret create and store logic to leverage this feature.The feature
flag needs to be used in related changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add functional test for new APIs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update/Add existing functional test around multiple backend support.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Current unit and functional test will be modified to reflect related changes.
New unit and functional test will be added for new &lt;cite&gt;secret-stores&lt;/cite&gt; APIs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;This is a new feature that will be documented for new APIs and its usage.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;1. Transport Key Wrapping
&lt;a class="reference external" href="https://github.com/openstack/barbican-specs/blob/master/specs/juno/add-wrapping-key-to-barbican-server.rst"&gt;https://github.com/openstack/barbican-specs/blob/master/specs/juno/add-wrapping-key-to-barbican-server.rst&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Wed, 23 Nov 2016 00:00:00 </pubDate></item><item><title>Deployer Specific Metadata for Secrets</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/newton/deployer-specific-secret-metadata.html</link><description>

&lt;p&gt;Blueprint:
&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/deployer-specific-secret-metadata"&gt;https://blueprints.launchpad.net/barbican/+spec/deployer-specific-secret-metadata&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Deployers(Service Admins) may require the ability to add additional data to
a Barbican Secret, which users cannot access/modify. The data must be immutable
for to the user, but a deployer should be able to change it. Secrets contain
immutable metadata such as &lt;cite&gt;created&lt;/cite&gt;, &lt;cite&gt;updated&lt;/cite&gt;, &lt;cite&gt;algorithm&lt;/cite&gt;, &lt;cite&gt;etc.&lt;/cite&gt;. The
deployer may want to add some data which is also immutable for the user. For
example, the deployer may want to store specifics such as the &lt;cite&gt;region&lt;/cite&gt; where
the secret is located.&lt;/p&gt;
&lt;p&gt;Currently only user metadata can be used, and it is not immutable to a user[1].&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The proposed change will be to add a new attribute to Barbican
Secrets in order for deployer meta-data to be stored. A new API
endpoint must also be created for the manipulation of the metadata.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Lock usage of metadata and have database admins add keys and values.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;A new table will be created called &lt;cite&gt;secret-deployer-metadata&lt;/cite&gt; with &lt;cite&gt;secret_id&lt;/cite&gt;,
&lt;cite&gt;key`and `value&lt;/cite&gt; columns.&lt;/p&gt;
&lt;p&gt;At the database level a limit will also be placed on the size of the
&lt;cite&gt;metadata&lt;/cite&gt;.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Values will all be stored as Strings.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Each current API call for Secrets will now have &lt;cite&gt;deployer-metadata&lt;/cite&gt; as an
added attribute. If no &lt;cite&gt;deployer-metadata&lt;/cite&gt; is provided then an empty dictionary will be
initialized.&lt;/p&gt;
&lt;p&gt;The following will be added to the REST API:&lt;/p&gt;
&lt;p&gt;Get deployer-metadata from a secret:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;deployer&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;
&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Project&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'deployer-metadata'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'contains the AES key'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'geolocation'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'12.3456, -98.7654'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Create/Update deployer-metadata for a secret:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;deployer&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;
&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Project&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'deployer-metadata'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'contains the AES key'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'geolocation'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'12.3456, -98.7654'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'deployer-metadata'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'contains the AES key'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'geolocation'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'12.3456, -98.7654'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Only Create/Update deployer-metadata will be needed. To remove the metadata
a user can perform the PUT with an empty dict. If a partial model is
sent then the whole metadata will be changed to the partial model which
has been sent. Values that exist in the data model but not in the PUT
will be deleted.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The following will be added to the REST API in order to address individual
user metadata items:&lt;/p&gt;
&lt;p&gt;Create an individual metadata item in a secret:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;deployer&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;
&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Project&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"access-limit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="mi"&gt;201&lt;/span&gt; &lt;span class="n"&gt;Created&lt;/span&gt;

&lt;span class="n"&gt;Secret&lt;/span&gt; &lt;span class="n"&gt;Metadata&lt;/span&gt; &lt;span class="n"&gt;Location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;9311&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;deployer&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;access&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;limit&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"access-limit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;If the item already exists then a 409 Conflict error
code will be returned.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Update an individual metadata item in a secret:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;deployer&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;access&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;limit&lt;/span&gt;
&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Project&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"access-limit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"access-limit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;access-limit must already have been created if not a 404 error code will
be returned.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Get an individual metadata item in a secret:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;deployer&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;access&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;limit&lt;/span&gt;
&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Project&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"access-limit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;If the &lt;cite&gt;access-limit&lt;/cite&gt; key does not exist then a 404 error code will
be returned.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Delete an individual metadata item in a secret:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;DELETE&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;deployer&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;access&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;limit&lt;/span&gt;
&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Project&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="mi"&gt;204&lt;/span&gt; &lt;span class="n"&gt;No&lt;/span&gt; &lt;span class="n"&gt;Content&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;If the &lt;cite&gt;access-limit&lt;/cite&gt; key does not exist then a 404 error code will
be returned.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;ACLs and Policy must be setup for the new API calls listed above.&lt;/p&gt;
&lt;p&gt;Barbican’s policy.json will now include the following:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;“secret-deployer-meta:get”: “rule:service_admin”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;“secret-deployer-meta:post”: “rule:service_admin”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;“secret-deployer-meta:put”: “rule:service_admin”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;“secret-deployer-meta:delete”: “rule:service_admin”&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h3&gt;Notifications &amp;amp; Audit Impact&lt;/h3&gt;
&lt;p&gt;If supported, adding/modifying secret-deployer-metadata should be audit events.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Minimal:&lt;/p&gt;
&lt;p&gt;A new table will be added to the database. It will include new alembic
scripts to create the new table and it’s associations.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Deployer will now have the ability to store secret specific metadata that may
be consumed by an application.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;diazjf&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Phase 1: Database alterations
Phase 2: Current and New API alterations and Tests
Phase 3: Documentation&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests must be written for internal component testing. Functional tests must
be written for testing this new feature as a whole.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Barbican API must be updated to include these changes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] &lt;a class="reference external" href="https://github.com/openstack/barbican-specs/blob/master/specs/mitaka/add-user-metadata.rst"&gt;https://github.com/openstack/barbican-specs/blob/master/specs/mitaka/add-user-metadata.rst&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Mon, 04 Apr 2016 00:00:00 </pubDate></item><item><title>Add KMIP key manager wrapper</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/mitaka/kmip-key-manager.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/castellan/+spec/kmip-key-manager"&gt;https://blueprints.launchpad.net/castellan/+spec/kmip-key-manager&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;KMIP[1] devices are key managers and since Castellan is a key manager
interface it seems likely that someone would want Castellan to go directly to
a KMIP device instead of a Barbican with a KMIP device on the backend. This
blueprint offers a solution to directly talk to a KMIP device using Castellan.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;In order to currently talk to a KMIP device with Castellan, Castellan must
first talk to a Barbican that is hooked up with a KMIP device on the backend.
By creating a KMIP key manager interface, Castellan can interact with the KMIP
device directly.&lt;/p&gt;
&lt;p&gt;This has the added benefit of allowing a client to decide whether or not
they require Barbican sitting in front of their KMIP device. Whether they have
their own device or purchase one from the cloud provider, they might not need
all of the Barbican functionality or resources and simply want a direct line
to the KMIP device.&lt;/p&gt;
&lt;p&gt;This will allow for a private or dedicated cloud to use Castellan without
needing Barbican.&lt;/p&gt;
&lt;p&gt;An important thing to keep in mind is that multi-tenancy is not guaranteed
with KMIP devices. Some devices offer the ability to create separate users
which does separate keys based on unique user accounts. However, not all
devices support this feature. Moreover, KMIP devices do not currently support
keystone as a means of authentication. The section below details the future
changes and possible support for both multi-tenancy and keystone
authentication.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;A module will be created titled &lt;strong&gt;kmip_key_manager&lt;/strong&gt;.
This module will live where the key manager interfaces live now and can be used
to directly interface with a KMIP device.&lt;/p&gt;
&lt;p&gt;In order for the KMIP key manager to take in a context object, two new
credential types needs to be created. One is Certificate which will just
take in the location of a certificate and the other is KMIP which will be
an extension of Certificate. The KMIP credential object will take in all
the necessary values in order to establish a connection to the KMIP device
including a certificate.&lt;/p&gt;
&lt;p&gt;The values used by the KMIP credential object will be the same variables used
by Barbican to establish a connection to a KMIP device and can be modified
via the castellan.conf file or through castellan itself. This will make it
possible for KMIP devices that support separate user accounts to provide
some multi-tenant capabilities.&lt;/p&gt;
&lt;p&gt;When KMIP devices start supporting keystone tokens, the KMIP key manager class
can be updated to take in either the KMIP credential object or keystone token
credential object as a context. This will allow for full multi-tenant
capabilities that we see today in Barbican.&lt;/p&gt;
&lt;p&gt;Here is an example of the new values that will be added to the &lt;cite&gt;castellan.conf&lt;/cite&gt;
file:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;kmip&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# From castellan.config&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;

&lt;span class="c1"&gt;# Username for user authorized to access KMIP device  (string value)&lt;/span&gt;
&lt;span class="c1"&gt;#username = admin&lt;/span&gt;

&lt;span class="c1"&gt;# Password for KMIP authenticated user (string value)&lt;/span&gt;
&lt;span class="c1"&gt;#password = password&lt;/span&gt;

&lt;span class="c1"&gt;# Use this endpoint to connect to the KMIP device (string value)&lt;/span&gt;
&lt;span class="c1"&gt;#host = localhost&lt;/span&gt;

&lt;span class="c1"&gt;# Port that KMIP device is listening on (string value)&lt;/span&gt;
&lt;span class="c1"&gt;#port = 5696&lt;/span&gt;

&lt;span class="c1"&gt;# Keyfile used by castellan (string value)&lt;/span&gt;
&lt;span class="c1"&gt;#keyfile = '/path/to/certs/cert.key'&lt;/span&gt;

&lt;span class="c1"&gt;# Certificate used by castellan to talk to KMIP device (string value)&lt;/span&gt;
&lt;span class="c1"&gt;#certfile = '/path/to/certs/cert.crt'&lt;/span&gt;

&lt;span class="c1"&gt;# List of certificates and CA's that castellan willaccept (string value)&lt;/span&gt;
&lt;span class="c1"&gt;#ca_certs = '/path/to/certs/LocalCA.crt'&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;These values can reside in the &lt;cite&gt;castellan.conf&lt;/cite&gt; file or can be added to an
already existing configuration file. Castellan just needs to be given the
location of the file to read.&lt;/p&gt;
&lt;p&gt;The rest of the code will be very similar to the KMIP secret store code
within Barbican.[2]&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;KMIP devices do not guarantee multi-tenant functionality.
This means users should be aware that when Castellan is the interface to the
KMIP device, any user that has access to the KMIP credentials might be able
to talk to the device. There is no differentiation based to the user’s role
or project because keystone cannot currently be used as a form of
authentication. This will need to be heavily documented.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h3&gt;Notifications &amp;amp; Audit Impact&lt;/h3&gt;
&lt;p&gt;Any CRUD request to the device will need to be logged.
Establishing and ending the connection should also be logged to make sure
the connection is successful and successfully terminated.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;silos (Christopher Solis)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Create a Certificate and KMIP credential object&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a KMIP key manager&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a KMIP section to the sample Castellan configuration file&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unit and functional test the key manager wrapper and credential objects&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;New unit tests and functional tests need to be added.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Castellan documentation should be updated to reflect the addition of the new
backend.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] &lt;a class="reference external" href="https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=kmip"&gt;https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=kmip&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[2] &lt;a class="reference external" href="https://github.com/openstack/barbican/blob/master/barbican/plugin/kmip_secret_store.py"&gt;https://github.com/openstack/barbican/blob/master/barbican/plugin/kmip_secret_store.py&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 17 Nov 2015 00:00:00 </pubDate></item><item><title>Allow Castellan to Support different types of Keystone Auth</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/mitaka/remove-keystone-dependancy.html</link><description>

&lt;p&gt;Blueprint:
&lt;a class="reference external" href="https://blueprints.launchpad.net/castellan/+spec/remove-keystone-dependency"&gt;https://blueprints.launchpad.net/castellan/+spec/remove-keystone-dependency&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Currently in Castellan in order to obtain access to Barbican via the Barbican
Key manager a &lt;cite&gt;context&lt;/cite&gt; containing a valid Keystone &lt;cite&gt;auth-token&lt;/cite&gt; must be
provided.&lt;/p&gt;
&lt;p&gt;The Swift Keymaster under development[1] will access Castellan in order to
obtain Secrets from Barbican, but would like to have a Keystone service user
with access to all keys and in the future be able to have independent user
access. For a service user, a &lt;cite&gt;context&lt;/cite&gt; containing a Keystone &lt;cite&gt;username&lt;/cite&gt;
and &lt;cite&gt;password&lt;/cite&gt; will be used. Castellan must support this.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The proposed change is to allow Castellan to be able to check the context for
the Barbican Key Manager and be able to determine what type of Keystone
authentication function to use.&lt;/p&gt;
&lt;p&gt;There will be a new type of hierarchal context object which will be passed from
the user/service to Castellan. It will be used instead of oslo.context.&lt;/p&gt;
&lt;p&gt;The hierarchal context will consist of a &lt;cite&gt;Credential&lt;/cite&gt; object as the parent
class and the children will be:&lt;/p&gt;
&lt;p&gt;1.) &lt;cite&gt;TokenCredential&lt;/cite&gt;, for authenticating with a token.&lt;/p&gt;
&lt;p&gt;2.) &lt;cite&gt;PasswordCredential&lt;/cite&gt;, for authenticating with a username and password.&lt;/p&gt;
&lt;p&gt;3.) &lt;cite&gt;CertificateCredential&lt;/cite&gt;, for authenticating with a certificate.&lt;/p&gt;
&lt;p&gt;The context is first checked to see what type of object it is, after that we
determine which Keystone auth-type to use.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;oslo.context still needs to be supported until it is deprecated in the
future. &lt;cite&gt;tenant&lt;/cite&gt; and &lt;cite&gt;project_id&lt;/cite&gt; should be backwards compatible. Patch
&lt;a class="reference external" href="https://review.openstack.org/#/c/235671/"&gt;https://review.openstack.org/#/c/235671/&lt;/a&gt; adds check for project_id, It
allows avoidance of confusion between &lt;cite&gt;tenant&lt;/cite&gt; and &lt;cite&gt;project_id&lt;/cite&gt; and is
necessary if passing a keystone auth-middleware object as context.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Example Usage within the swift keymaster:&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;castellan.common.objects&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;symmetric_key&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;castellan&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;credential&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;castellan&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;key_manager&lt;/span&gt;

&lt;span class="n"&gt;CONF&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;swift&lt;/span&gt; &lt;span class="n"&gt;conf&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c1"&gt;# If keystone auth-middleware exists then it provides the authentication&lt;/span&gt;
&lt;span class="c1"&gt;# for the logged in user[2].&lt;/span&gt;
&lt;span class="n"&gt;ks_context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'keystone.token_auth'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;

&lt;span class="c1"&gt;# Depending on how the configuration is setup, then a different 'credential` object&lt;/span&gt;
&lt;span class="c1"&gt;# will be created and processed by Castellan. More information on this can be&lt;/span&gt;
&lt;span class="c1"&gt;# found in examples below.&lt;/span&gt;
&lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;credential&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;credential_factory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ks_context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;conf&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;CONF&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# create a key&lt;/span&gt;
&lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;symmetric_key&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SymmetricKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'aes'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'==8hykeh'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;manager&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;key_manager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;API&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;configuration&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;CONF&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;stored_key_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;manager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The swift configuration must be altered to contain certain variables that
Castellan will use for authentication.&lt;/p&gt;
&lt;p&gt;For password-based authentication the user must provide the following in the
Swift Configuration:&lt;/p&gt;
&lt;div class="highlight-ini notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;[castellan]&lt;/span&gt;
&lt;span class="na"&gt;auth_type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;'password'&lt;/span&gt;
&lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;'swift'&lt;/span&gt;
&lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;'xswift'&lt;/span&gt;
&lt;span class="na"&gt;project_id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;'1a4a0618b306462c9830f876b0bd6af2'&lt;/span&gt;
&lt;span class="na"&gt;domain_id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;'5abc43'&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;The above is an example on how it can be used in the Swift Keymaster. It is
just provided for demonstration purposes.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;cite&gt;auth_type&lt;/cite&gt; variable will be used in order to determine what type of &lt;cite&gt;credential&lt;/cite&gt;
Castellan should create. The possible auth_types will be &lt;cite&gt;token&lt;/cite&gt;, &lt;cite&gt;password&lt;/cite&gt; and
&lt;cite&gt;certificate&lt;/cite&gt;. Castellan will contain a context factory in order to process
the different auth_types. Below is an example of the context factory.&lt;/p&gt;
&lt;div class="highlight-python notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;credential_factory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;conf&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;CONF&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;castellan&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;auth_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;'token'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;auth_token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;auth_token&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;auth_token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CONF&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;castellan&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;auth_token&lt;/span&gt;

        &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;catstellan&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;KeystoneTokenContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auth_token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                                  &lt;span class="n"&gt;CONF&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;castellan&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;auth_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                                  &lt;span class="n"&gt;CONF&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;castellan&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;CONF&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;castellan&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;auth_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;'password'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;castellan&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PasswordContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CONF&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;castellan&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                            &lt;span class="n"&gt;CONF&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;castellan&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                            &lt;span class="n"&gt;CONF&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;castellan&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;auth_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                            &lt;span class="n"&gt;CONF&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;castellan&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                            &lt;span class="n"&gt;CONF&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;castellan&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;domain_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;CONF&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;castellan&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;auth_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;'certificate'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;castellan&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CertificateContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CONF&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;castellan&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;public_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                               &lt;span class="n"&gt;CONF&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;castellan&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;private_key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;A Keystone Auth-Token can be derived using Username and Password. An
oslo.context object containing the Auth-Token can be created and passed to a
Castellan call.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;If v3.Password is being used, then the username, password, project_id, and
domain information(id or name) must be stored.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h3&gt;Notifications &amp;amp; Audit Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="python-and-command-line-client-impact"&gt;
&lt;h3&gt;Python and Command Line Client Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Developer has more options of context that can be passed to Castellan.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;diazjf&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;rellerreller&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;1. Create support for multiple Keystone auth types in Castellan for the
Barbican Key manager.
2. Add documentation on how to generate context for the Barbican Key Manager.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;New unit tests and functional tests need to be added.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Castellan documentation must be updated to include these changes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] &lt;a class="reference external" href="https://github.com/openstack/swift-specs/blob/master/specs/in_progress/at_rest_encryption.rst"&gt;https://github.com/openstack/swift-specs/blob/master/specs/in_progress/at_rest_encryption.rst&lt;/a&gt;
[2] &lt;a class="reference external" href="https://github.com/openstack/keystonemiddleware/blob/1047cececf68c3c22add66b6a8a1c499a667c036/keystonemiddleware/auth_token/__init__.py#L171-L174"&gt;https://github.com/openstack/keystonemiddleware/blob/1047cececf68c3c22add66b6a8a1c499a667c036/keystonemiddleware/auth_token/__init__.py#L171-L174&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Mon, 02 Nov 2015 00:00:00 </pubDate></item><item><title>Add User Metadata to Barbican Secrets</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/mitaka/add-user-metadata.html</link><description>

&lt;p&gt;Blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/add-user-metadata"&gt;https://blueprints.launchpad.net/barbican/+spec/add-user-metadata&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Client Blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/python-barbicanclient/+spec/add-user-metadata"&gt;https://blueprints.launchpad.net/python-barbicanclient/+spec/add-user-metadata&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Currently the only unique information that can be generated for a Barbican
Secret by a user is &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;name&lt;/span&gt;&lt;/code&gt;. This blueprint will add a new field to each
Barbican Secret to allow a user to add their own metadata to the Secret.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Users may require to add additional data to a Barbican Secret. A user may
want to add a description of the Secret as well as other necessary data
such as geolocation, rate, allowed time-access, etc. This will allow user
applications/services to check the user-metadata for certain fields in order
to allow/disallow an action to Barbican.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The proposed change will be to add a new attribute to Barbican
Secrets in order for user meta-data to be stored. A new API
endpoint must also be created for the manipulation of the metadata.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Currently there are no alternatives, since user is not able to add
any unique information other than to the attribute &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;name&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;Secrets will now have an additional parameter called &lt;cite&gt;metadata&lt;/cite&gt;.
&lt;cite&gt;metadata&lt;/cite&gt; will be a dictionary in which a user can add a key and
a value.&lt;/p&gt;
&lt;p&gt;A limit must also be set as to how much meta-data a user can add to a
secret. &lt;cite&gt;quota_secret_meta&lt;/cite&gt; will be added to the Barbican config and set to
&lt;cite&gt;-1&lt;/cite&gt;, which allows for unlimited metadata.&lt;/p&gt;
&lt;p&gt;At the database level a limit will also be placed on the size of the
&lt;cite&gt;metadata&lt;/cite&gt;.&lt;/p&gt;
&lt;p&gt;A new table will be created called &lt;cite&gt;secret-metadata&lt;/cite&gt; with &lt;cite&gt;secret_id&lt;/cite&gt;, &lt;cite&gt;key&lt;/cite&gt;
and &lt;cite&gt;value&lt;/cite&gt; columns.&lt;/p&gt;
&lt;p&gt;This has the following benefits:&lt;/p&gt;
&lt;p&gt;1. Searching Benefits
The value column can be used to search and the search can stop once an invalid
character is found. Indexing on keys can also be done to make searching for
keys with a certain tag faster.&lt;/p&gt;
&lt;p&gt;2. Extensibility
If we wish to add new information, such as created-timestamp,
updated-timestamp, etc. we can simply add a new column. This is cleaner
than adding some other system.&lt;/p&gt;
&lt;p&gt;3. Data Consistency
Restrictions can be done at the database level, such as length of the
key/value strings. Number of metadata items can be limited by adding
column restrictions. This will provide good measures for data integrity, and
strengthen security.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Values will all be stored as Strings.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Each Current API call for Secrets will now have &lt;cite&gt;metadata&lt;/cite&gt; as an added
attribute. If no &lt;cite&gt;metadata&lt;/cite&gt; is provided then an empty dictionary will be
initialized.&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;
&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Project&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"AES key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"expiration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2015-12-28T19:14:44.180394"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"algorithm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"aes"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"bit_length"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"cbc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"payload"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"YmVlcg=="&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"payload_content_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/octet-stream"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"payload_content_encoding"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"base64"&lt;/span&gt;
    &lt;span class="s2"&gt;"metadata"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'contains the AES key'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s1"&gt;'geolocation'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'12.3456, -98.7654'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="mi"&gt;201&lt;/span&gt; &lt;span class="n"&gt;Created&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"secret_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"https://&lt;/span&gt;&lt;span class="si"&gt;{barbican_host}&lt;/span&gt;&lt;span class="s2"&gt;/v1/secrets/&lt;/span&gt;&lt;span class="si"&gt;{uuid}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Project&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ACTIVE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"created"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2015-03-23T20:46:51.650515"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"updated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2015-03-23T20:46:51.654116"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"expiration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2015-12-28T19:14:44.180394"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"algorithm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"aes"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"bit_length"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"cbc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"AES key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"secret_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"https://&lt;/span&gt;&lt;span class="si"&gt;{barbican_host}&lt;/span&gt;&lt;span class="s2"&gt;/v1/secrets/&lt;/span&gt;&lt;span class="si"&gt;{secret_uuid}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"secret_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"opaque"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"content_types"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"default"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/octet-stream"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="s2"&gt;"metadata"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'contains the AES key'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s1"&gt;'geolocation'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'12.3456, -98.7654'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;If no &lt;cite&gt;metadata&lt;/cite&gt; is input on the POST then &lt;cite&gt;metadata&lt;/cite&gt; will
not be shown.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The following will be added to the REST API:&lt;/p&gt;
&lt;p&gt;Get user-metadata from a secret:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;
&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Project&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'metadata'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'contains the AES key'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'geolocation'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'12.3456, -98.7654'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Create/Update user-metadata for a secret:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;
&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Project&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'metadata'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'contains the AES key'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'geolocation'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'12.3456, -98.7654'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s1"&gt;'metadata'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'description'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'contains the AES key'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'geolocation'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'12.3456, -98.7654'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Only Create/Update user-metadata will be needed. To remove the metadata
a user can perform the PUT with an empty dict. If a partial model is
sent then the whole metadata will be changed to the partial model which
has been sent. Values that exist in the data model but not in the PUT
will be deleted.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The following will be added to the REST API in order to address individual
user metadata items:&lt;/p&gt;
&lt;p&gt;Create an individual metadata item in a secret:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;
&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Project&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"access-limit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="mi"&gt;201&lt;/span&gt; &lt;span class="n"&gt;Created&lt;/span&gt;

&lt;span class="n"&gt;Secret&lt;/span&gt; &lt;span class="n"&gt;Metadata&lt;/span&gt; &lt;span class="n"&gt;Location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;9311&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;access&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;limit&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"access-llimit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;If the item already exists then a 409 Conflict error
code will be returned.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Update an individual metadata item in a secret:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;access&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;limit&lt;/span&gt;
&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Project&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"access-limit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"access-limit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;access-limit must already have been created if not a 404 error code will
be returned.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Get an individual metadata item in a secret:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;access&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;limit&lt;/span&gt;
&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;
    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Project&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"access-limit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;If the &lt;cite&gt;access-limit&lt;/cite&gt; key does not exist then a 404 error code will
be returned.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Delete an individual metadata item in a secret:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;DELETE&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;access&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;limit&lt;/span&gt;
&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Project&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;project_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="mi"&gt;204&lt;/span&gt; &lt;span class="n"&gt;No&lt;/span&gt; &lt;span class="n"&gt;Content&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;If the &lt;cite&gt;access-limit&lt;/cite&gt; key does not exist then a 404 error code will
be returned.&lt;/p&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;ACLs and Policy must be setup for the new API calls listed above.&lt;/p&gt;
&lt;p&gt;Barbican’s policy.json will now include the following:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;“secret-meta:get”: “rule:secret_non_private_read or rule:secret_project_creator
or rule:secret_project_admin or rule:secret_acl_read”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;“secret-meta:post”: “rule:admin_or_creator and rule:secret_project_match”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;“secret-meta:put”: “rule:admin_or_creator and rule:secret_project_match”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;“secret-meta:delete”: “rule:admin_or_creator and rule:secret_project_match”&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h3&gt;Notifications &amp;amp; Audit Impact&lt;/h3&gt;
&lt;p&gt;If supported, adding/modifying secret-metadata should be audit events.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="python-and-command-line-client-impact"&gt;
&lt;h3&gt;Python and Command Line Client Impact&lt;/h3&gt;
&lt;p&gt;The following commands will need to be added to the CLI:&lt;/p&gt;
&lt;p&gt;Secrets:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Secret&lt;/span&gt; &lt;span class="n"&gt;Metadata&lt;/span&gt; &lt;span class="n"&gt;Update&lt;/span&gt;
&lt;span class="n"&gt;Secret&lt;/span&gt; &lt;span class="n"&gt;Metadatum&lt;/span&gt; &lt;span class="n"&gt;Update&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Minimal:&lt;/p&gt;
&lt;p&gt;A new table will be added to the database. It will include new alembic
scripts to create the new table and it’s associations.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Deployer will now need to know to set &lt;cite&gt;quota_secret_meta&lt;/cite&gt; if they wish users to
be able to add less &lt;cite&gt;metadata&lt;/cite&gt; keys to a secret.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;diazjf&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Phase 1: Database alterations
Phase 2: Current and New API alterations and Tests
Phase 3: Add Functionality to CLI&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests must be written for internal component testing. Functional tests must
be written for testing this new feature as a whole.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Barbican API and Barbican Client must be updated to include these changes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/add-user-metadata"&gt;https://blueprints.launchpad.net/barbican/+spec/add-user-metadata&lt;/a&gt;
&lt;a class="reference external" href="https://blueprints.launchpad.net/python-barbicanclient/+spec/add-user-metadata"&gt;https://blueprints.launchpad.net/python-barbicanclient/+spec/add-user-metadata&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 01 Oct 2015 00:00:00 </pubDate></item><item><title>Add quota support for Barbican resources</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/liberty/quota-support-for-barbican-resources.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/quota-support-on-barbican-resources"&gt;https://blueprints.launchpad.net/barbican/+spec/quota-support-on-barbican-resources&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Barbican REST API doesn’t impose any upper limit on the number of resources
allowed per project. This could result in resource explosion. This blueprint
proposes a way to specify and enforce quotas with projects. Quotas are
operational limits so that cloud resources are optimized.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Here are few scenarios that could impact the normal functioning of the
Barbican server:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A client could place requests for several thousands of orders to create
secrets for a single project. This might overwhelm the Barbican server
both in terms of processing time and disk space consumed&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If a buggy client script runs amok and attempts to create a generic
type container with no associated secret, it could quickly fill-up
the Barbican database!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If a user creates a large number of projects and further creates a
large number of Barbican resources per these projects, that could
impact other genuine users&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note: The last point could be avoided if keystone could enforce a
upper limit on the number of projects that an user could create. Hence
this is treated as a lower priority for Barbican for now. This spec
aims to implement project level quotas first. A later spec is expected
to add support for user level quotas.&lt;/p&gt;
&lt;p&gt;This is similar to the quota enforcement done by nova and cinder
services.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Introduce quotas for all Barbican resources. The quotas should have
unlimited values as defaults, to ensure backwards compatibility with
the current code that supports no quotas. The following resources will
have quota support:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;secrets&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;orders&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;containers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;consumers&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This proposal is a simpler subset of the quota implementation done
by Nova and Cinder. Barbican does not have any reservable resources
and so the quotas are much simpler in that there is no usage tracking and
reservations. Also, project-user level quota enforcement is not covered
by this spec.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;*Enforcing quotas:*&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Barbican API controllers will be updated with quota logic for the
create resource methods. Once implemented, the quota check will work
as follows for resource creation requests:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Get the quotas for the project retrieved from the auth context.
If per-project quotas have not been setup, use default quotas&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get a count of the resources for the context project
Note: Currently secrets that expire or are removed are not hard removed
from the database, but rather are soft deleted, so they still are using
resources within Barbican and would be counted against the project’s
quota. However, this is deployment dependent. A deployment could have a
process that hard removes such resources after a period of time&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the count equals or exceeds the quotas, reject the request with
the following error message:
HTTP 403 Forbidden
{“error”: “Quota exceeded for &amp;lt;project_id&amp;gt;. Only &amp;lt;count&amp;gt; &amp;lt;resource&amp;gt;s
are allowed”
}&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Continue with the resource creation&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Update the Barbican config file to include the following section for
quota limits:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="c1"&gt;# ====================== Quota Options ===============================&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;quotas&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;# For each resource, the default maximum number that can be used for&lt;/span&gt;
&lt;span class="c1"&gt;# a project is set below.  This value can be overridden for each&lt;/span&gt;
&lt;span class="c1"&gt;# project through the API.  A negative value means no limit.  A zero&lt;/span&gt;
&lt;span class="c1"&gt;# value effectively disables creation of the resource.&lt;/span&gt;

&lt;span class="c1"&gt;# default number of secrets allowed per project&lt;/span&gt;
&lt;span class="n"&gt;quota_secrets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="c1"&gt;# default number of orders allowed per project&lt;/span&gt;
&lt;span class="n"&gt;quota_orders&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="c1"&gt;# default number of containers allowed per project&lt;/span&gt;
&lt;span class="n"&gt;quota_containers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="c1"&gt;# default number of consumers allowed per project&lt;/span&gt;
&lt;span class="n"&gt;quota_consumers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;A number &amp;gt;=0 for the quota_&amp;lt;value&amp;gt; indicates the max
limit for that resource and a negative value means unlimited.  A value
of zero indicates a maximum of zero instances of that resource, effectively
disabling creation of that entity.  To ensure backwards compatibility, the
provided default for the defaults will be -1 (unlimited) for each resource.&lt;/p&gt;
&lt;p&gt;While these generic quotas apply to all projects, there will
also be support to define and enforce quotas per project.
The priority in which the quotas are enforced is then:
[per project quotas] =&amp;gt; [default quotas]&lt;/p&gt;
&lt;p&gt;where,
“per project quotas” - these quotas are directly associated with a particular
project id. Any changes to these quotas will impact only that project.&lt;/p&gt;
&lt;p&gt;“default quotas” - if no per project quotas are specified, the
default quotas are used. These would typically be the values supplied in the
config file.&lt;/p&gt;
&lt;p&gt;The default quotas are stored in the config file (as shown above) but
per-project quotas are stored in db.&lt;/p&gt;
&lt;p&gt;A REST API for Barbican administrators for the quota CRUD operations will be
implemented as well. Non-admin users will be provided with a REST API to get
their own effective quotas for various resources. Keystone RBAC checks will
be employed to decide if a caller has the required role to perform
these operations.&lt;/p&gt;
&lt;p&gt;Quota management should be under the purview of a service level administrator,
not a project level administrator.  In the current Barbican implementation,
there are four user roles: admin, creator, observer, and auditor.  All
of these roles are project level.  Thus, to accomplish appropriate role
based access to for quota a management, a new role will be created.  The
name of this role will be “key-manager:service-admin”.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;An attempt was made to create an oslo.common library with quota support
for all OpenStack projects.  The first attempt was committed to oslo, however
it has been deprecated and has not been adopted by any projects.  A second
attempt was started, but has been put on hold with no current plans to restart.
There is no other common OpenStack library implementing quotas for Barbican
to adopt.&lt;/p&gt;
&lt;p&gt;The quota configuration and logic will be derived by looking at quota
implementations done by other OpenStack projects like nova, cinder
and neutron.  A simplified implementation will developed for Barbican by
using APIs and logic similar to Nova’s implementation, while removing unneeded
features, such as pluggable backend drivers and resource reservation.&lt;/p&gt;
&lt;p&gt;Another alternative is an initiative by Kevin Mitchell from Rackspace
&lt;a class="reference external" href="https://wiki.openstack.org/wiki/Boson"&gt;https://wiki.openstack.org/wiki/Boson&lt;/a&gt;. However, the Nova and Cinder design
is more usable for Barbican.&lt;/p&gt;
&lt;p&gt;In addition to the four resources specified above, a previous version of this
spec described implementing quotas support for transport_keys.  This is not
possible based on the current implementation of transport_keys, because they
are defined per-plugin and not per-project.  A project admin should not
be managing transport_keys at all.&lt;/p&gt;
&lt;p&gt;The name of the role required to manage project quotas is decided to be
“key-manager:service-admin”.  This foreshadows a future change where all
Barbican roles might be defined with a namespace of key-manager.  A variety
of other role names (“service-admin”, “barbican-admin”, “cloud-admin”) were
are also possible alternatives.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;The following new data models will be added:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;ProjectQuota&lt;/p&gt;
&lt;p&gt;Represents quotas override for a project.&lt;/p&gt;
&lt;p&gt;If there is no row for a given project id, then the
default for the deployment is used.  If the quota value for a resource
is null, then the default for that resource for the deployment is used.
If the quota value for a resource is 0, creation of that resource is
disabled.  If the quota value for a resource is -1, creation of that
resource is not limited by quota enforcement logic.&lt;/p&gt;
&lt;p&gt;Schema: (table name: &lt;strong&gt;project_quotas&lt;/strong&gt;)&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;project_id:     String(36) ForeignKey projects.id, nullable=False&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;secrets:        Integer, nullable=True&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;orders:         Integer, nullable=True&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;containers:     Integer, nullable=True&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;consumers:      Integer, nullable=True&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;&lt;strong&gt;Constraints&lt;/strong&gt;: project_id must be unique&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;project_id must exist as projects.id&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Changes to existing models:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;No existing models will be impacted by this addition. However, it needs
to be investigated if new indexes need to be built to speed up resource
consumption lookups.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;The following new REST API will be implemented to manage quotas CRUD
operations. Please note that except for the first GET API, all the
other APIs require the caller to have “key-manager:service-admin” role.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Get effective quotas (any Barbican user)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Returns effective resource quotas for the caller for the specified
project. If there are no project specific quotas returns the
deployment default resource limits.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GET /v1/quotas&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Normal http response code(s)
200 OK&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Expected error http response code(s)&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;401 Unauthorized - If the auth token is not present or invalid.&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Also, if using the unauthenticated context and
the X-Project-Id header is not present in the request.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Required request headers&lt;/p&gt;
&lt;p&gt;X-Auth-Token, if using keystone auth&lt;/p&gt;
&lt;p&gt;X-Project-Id, if using unauthenticated context&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Parameters&lt;/p&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JSON schema definition for the body data if allowed&lt;/p&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JSON schema definition for the response data if any&lt;/p&gt;
&lt;p&gt;EXAMPLE:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'object'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'properties'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s1"&gt;'quotas'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'object'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'properties'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="s1"&gt;'secrets'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s1"&gt;'integer'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="s1"&gt;'orders'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s1"&gt;'integer'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="s1"&gt;'containers'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s1"&gt;'integer'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="s1"&gt;'consumers'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s1"&gt;'integer'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
         &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="s1"&gt;'additionalProperties'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="s1"&gt;'additionalProperties'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Example 1:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="n"&gt;non&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;admin&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="n"&gt;checking&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt; &lt;span class="n"&gt;quotas&lt;/span&gt; &lt;span class="n"&gt;using&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="n"&gt;scoped&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="n"&gt;particular&lt;/span&gt; &lt;span class="n"&gt;project&lt;/span&gt;

&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

  &lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;quotas&lt;/span&gt;

  &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

  &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;

  &lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;

  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"quotas"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"secrets"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"orders"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"containers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"consumers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List all project quotas (service-admin only)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Lists all configured project level resource quotas across all users for all
projects. If a project does not have project specific quotas configured,
that project is not included in the returned list.
If there are only project specific quotas for a subset of resources
for a project, this call will return null for those resources without a
configured value in that project. The returned list will be sorted
by create date, and support standard limit/offset paging.&lt;/p&gt;
&lt;p&gt;The standard paging support includes adding three fields in the
response body, when applicable.&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;“total”: showing the number of project-quotas records&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;“next”: giving a URL to the next page of records&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;“prev”: giving a URL to the previous page of records&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GET /v1/project-quotas?limit=x&amp;amp;offset=y (service-admin only)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Normal http response code(s)
200 OK&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Expected error http response code(s)&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;401 Unauthorized - If the auth token is not present or invalid.&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Also, if using the unauthenticated context and
the X-Project-Id header is not present in the request.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Required request headers&lt;/p&gt;
&lt;p&gt;X-Auth-Token, if using keystone auth&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Parameters&lt;/p&gt;
&lt;p&gt;limit(optional), integer, maximum number of records retrieved
offset(optional), integer, number of records to skip&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JSON schema definition for the body data if allowed&lt;/p&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JSON schema definition for the response data if any&lt;/p&gt;
&lt;p&gt;EXAMPLE:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'object'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'properties'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s1"&gt;'project_quotas'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'array'&lt;/span&gt;
        &lt;span class="s1"&gt;'items'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'object'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s1"&gt;'properties'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
             &lt;span class="s1"&gt;'project_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s1"&gt;'string'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
             &lt;span class="s1"&gt;'project_quotas'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                  &lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s1"&gt;'object'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="s1"&gt;'properties'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                     &lt;span class="s1"&gt;'secrets'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'integer'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                     &lt;span class="s1"&gt;'orders'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'integer'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                     &lt;span class="s1"&gt;'containers'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'integer'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                     &lt;span class="s1"&gt;'consumers'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'integer'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                  &lt;span class="p"&gt;}&lt;/span&gt;
             &lt;span class="p"&gt;}&lt;/span&gt;
           &lt;span class="p"&gt;}&lt;/span&gt;
         &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
     &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="s1"&gt;'additionalProperties'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Example 1:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="n"&gt;service&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;admin&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="n"&gt;listing&lt;/span&gt; &lt;span class="nb"&gt;all&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;project&lt;/span&gt; &lt;span class="n"&gt;quotas&lt;/span&gt;

&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

  &lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;quotas&lt;/span&gt;

  &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

  &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;

  &lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;

  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"project_quotas"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"1234"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_quotas"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
             &lt;span class="s2"&gt;"secrets"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"orders"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"containers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"consumers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;
         &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"project_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"5678"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"project_quotas"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
             &lt;span class="s2"&gt;"secrets"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"orders"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"containers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"consumers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;
         &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s2"&gt;"total"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Example 2:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;A service-admin user listing all the project quotas with paging

Request:

  GET /v1/project-quotas?limit=2&amp;amp;offset=6

  X-Auth-Token:&amp;lt;token&amp;gt;

Response:

  200 OK

  Content-Type: application/json

  {
    "project_quotas": [
      {
        "project_id": "1234",
        "project_quotas": {
             "secrets": 2000,
             "orders": 0,
             "containers": -1,
             "consumers": null
         }
      },
      {
        "project_id": "5678",
        "project_quotas": {
             "secrets": 200,
             "orders": 100,
             "containers": -1,
             "consumers": null
         }
      },
    ],
    "total" : 30,
    "next": "http://localhost:9311/v1/project_quotas?limit=2&amp;amp;offset=8",
    "prev": "http://localhost:9311/v1/project_quotas?limit=2&amp;amp;offset=4"
  }
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get quotas for a specific project (service-admin only)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Returns a set of configured resource quotas for the specified project.
If no project specific quota values have been configured (or if the
project does not exist), the API responds with Not Found.  If there are
only project specific quotas for a subset of resources for a project, this
call will return null for those resources without a configured value in
that project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GET /v1/project-quotas/{project_id}&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Normal http response code(s)
200 OK&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Expected error http response code(s)&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;401 Unauthorized - If the auth token is not present or invalid.&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Also, if using the unauthenticated context and
the X-Project-Id header is not present in the request.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;404 Not Found - If there are no project quota settings to delete&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;for the specified project.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Required request headers&lt;/p&gt;
&lt;p&gt;X-Auth-Token, if using keystone auth&lt;/p&gt;
&lt;p&gt;X-Project-Id, if using unauthenticated context&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JSON schema definition for the body data if allowed
None&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JSON schema definition for the response data if any:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'object'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'properties'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="s1"&gt;'project_quotas'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s1"&gt;'object'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s1"&gt;'properties'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s1"&gt;'secrets'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'integer'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="s1"&gt;'orders'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'integer'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="s1"&gt;'containers'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'integer'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="s1"&gt;'consumers'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'integer'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="s1"&gt;'additionalProperties'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

  &lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;quotas&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;1234&lt;/span&gt;

  &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

  &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;

  &lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;

  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"project_quotas"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"secrets"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"orders"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"containers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"consumers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update/Set quotas for a specific project (service-admin only)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Creates or updates the configured resource quotas for the specified
project. It is not required to specify limits for all Barbican resources.
If a value for a resource is not specified, the default limits will be
used for that resource.  If the specified project is not previously
known to Barbican, a new entry to the projects table will be created.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PUT /v1/project-quotas/{project_id}&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Normal http response code(s)&lt;/p&gt;
&lt;p&gt;204 No Content&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Expected error http response code(s)&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;401 Unauthorized - If the auth token is not present or invalid.&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Also, if using the unauthenticated context and
the X-Project-Id header is not present in the request.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;400 Bad Request - If the request payload doesn’t confirm to schema&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Required request headers&lt;/p&gt;
&lt;p&gt;X-Auth-Token, if using keystone auth&lt;/p&gt;
&lt;p&gt;X-Project-Id, if using unauthenticated context&lt;/p&gt;
&lt;p&gt;Content-Type, application/json&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JSON schema definition for the body data if allowed:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'object'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'properties'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="s1"&gt;'project_quotas'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s1"&gt;'object'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s1"&gt;'properties'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
             &lt;span class="s1"&gt;'secrets'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'integer'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
             &lt;span class="s1"&gt;'orders'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'integer'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
             &lt;span class="s1"&gt;'containers'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'integer'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
             &lt;span class="s1"&gt;'consumers'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'integer'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="p"&gt;},&lt;/span&gt;
 &lt;span class="s1"&gt;'additionalProperties'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JSON schema definition for the response data if any::
None&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

  &lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;quotas&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;1234&lt;/span&gt;

  &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;

    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"project_quotas"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"secrets"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"orders"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"containers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

  &lt;span class="mi"&gt;204&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete quotas for a specific project (service-admin only)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Deletes the configured resource quotas for the specified
project.  After this call succeeds, the default resource quotas will be
returned for subsequent calls by the user to list effective quotas.  If
there are no project specific quota configuration, or the project is
not previously known in Barbican, Not Found is returned.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DELETE v1/project-quotas/{project_id}&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Parameters
None&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Normal http response code(s)
204 No Content&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Expected error http response code(s)&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;401 Unauthorized - If the auth token is not present or invalid.&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;Also, if using the unauthenticated context and
the X-Project-Id header is not present in the request.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;404 Not Found - If there are no project quota settings to delete&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;for the specified project or the project is unknown
to Barbican.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Required request headers&lt;/p&gt;
&lt;p&gt;X-Auth-Token, if using keystone auth&lt;/p&gt;
&lt;p&gt;X-Project-Id, if using unauthenticated context&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Parameters&lt;/p&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JSON schema definition for the body data if allowed&lt;/p&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;JSON schema definition for the response data if any&lt;/p&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Example 1:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

  &lt;span class="n"&gt;DELETE&lt;/span&gt; &lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;quotas&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;1234&lt;/span&gt;

  &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;


&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

  &lt;span class="mi"&gt;204&lt;/span&gt; &lt;span class="n"&gt;No&lt;/span&gt; &lt;span class="n"&gt;Content&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Policy changes&lt;/p&gt;
&lt;p&gt;For all service-admin-only APIs, the caller is expected to have a barbican
key-manager:service-admin role. The check for this will be added to the
Barbican policy.json file.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once implemented and enforced, all Barbican resource creation API could return
a new error message back to the client if the request exceeded the allowed
quota limits.&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;

  &lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;

  &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;

  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;# payload to create secret&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;

  &lt;span class="mi"&gt;403&lt;/span&gt; &lt;span class="n"&gt;Forbidden&lt;/span&gt;

  &lt;span class="n"&gt;Retry&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;After&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

  &lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;

 &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Quota exceeded for &amp;lt;project-id&amp;gt;. Only &amp;lt;count&amp;gt; &amp;lt;resource&amp;gt;s&lt;/span&gt;
            &lt;span class="n"&gt;are&lt;/span&gt; &lt;span class="n"&gt;allowed&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Class Quotas&lt;/p&gt;
&lt;p&gt;Class level quotas are not addressed in this spec. Need another spec to cover the
data model impact and REST API for associated CRUD operations.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h3&gt;Notifications &amp;amp; Audit Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;The Barbican client (python-barbicanclient) has to be enhanced to consume
the Quota REST API mentioned. The following scenarios should be supported.&lt;/p&gt;
&lt;p&gt;Quota commands that a regular non-admin barbican user can make:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;List all quotas&lt;/p&gt;
&lt;p&gt;barbican quota show&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Quota commands that only a barbican service-admin can make&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;List the default quotas applicable to all new projects&lt;/p&gt;
&lt;p&gt;barbican quota show&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;List quotas for a specific project&lt;/p&gt;
&lt;p&gt;barbican quota show –project_id &amp;lt;project&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update quotas for a specific project&lt;/p&gt;
&lt;p&gt;barbican quota update –project_id &amp;lt;project&amp;gt; –secrets 50 –orders 10&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete per-project quotas for a project&lt;/p&gt;
&lt;p&gt;barbican quota delete –project_id &amp;lt;project&amp;gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;TBD&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;The new data models introduced will be added by a new Alembic version file.
If automatic migration is turned OFF, the db migration tool has to be run
manually to effect the changes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Developers integrating with Barbican API/client now need to handle the case
where the server could return a quota violation error&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Dave McCowan (dave-mccowan) will be leading the implementation of the code.&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&amp;lt;dave-mccowan&amp;gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Other assignees:&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Quota db provider source code&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Data model additions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Alembic migration version script&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Updated default config file with quota section&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;python-barbicanclient enhancements to support quota operations&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New unit tests to test quota related source changes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update existing resource unit tests to handle quota violation errors&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Functional tests&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;TBD&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;New unit tests and functional tests need to be added.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;A new section about Quotas has to be documented&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Existing resource API documentation needs to be updated with quota violation
specific errors&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;TBD&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 18 Aug 2015 00:00:00 </pubDate></item><item><title>Add List of Group-IDs to ACL for Secrets and Containers</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/liberty/api-acl-add-group-list.html</link><description>

&lt;p&gt;The URL to the launchpad blueprint is here:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/api-acl-add-group-list"&gt;https://blueprints.launchpad.net/barbican/+spec/api-acl-add-group-list&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The current access control list (ACL) approach in Barbican only allows for
adding user IDs for access to a given secret or container. This blueprint
proposes allowing group IDs to be added to ACLs to accommodate users within
specified groups access to secrets/containers as well. Adding group support to
ACLs would support LDAP group based access to secrets/containers. This
blueprint depends on the approval of a Keystone blueprint [1].&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Organizations with many users could find managing access to Barbican secrets at
the per-user level via the current ACL approach a significant effort.
Likewise for engineering systems that wish to manage access to secrets for
many devices. An approach to simplify access configuration would be to manage
secret and container access at the user group level, as proposed by this
blueprint.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The proposed approach is to add a new one-to-many reference on the current
&lt;cite&gt;SecretACL&lt;/cite&gt; entity called &lt;cite&gt;SecretACLGroup&lt;/cite&gt; which would be very similar to the
&lt;cite&gt;SecretACLUser&lt;/cite&gt; entity, except with a &lt;cite&gt;group_id&lt;/cite&gt; attribute that refers to
a desired group-ID to allow secret access to. Likewise a new
&lt;cite&gt;ContainerACLGroup&lt;/cite&gt; entity would be added and referenced via the current
&lt;cite&gt;ContainerACL&lt;/cite&gt; entity.&lt;/p&gt;
&lt;p&gt;In the &lt;cite&gt;barbican.api.controllers&lt;/cite&gt;’s &lt;cite&gt;acls.py&lt;/cite&gt; module, a new ‘groups’ element
within each ACL operation would be added, and handled similarly to the ‘users’
element now.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;The ‘Proposed Change’ section calls for adding two new entities:
&lt;cite&gt;SecretACLGroup&lt;/cite&gt; and &lt;cite&gt;ContainerACLGroup&lt;/cite&gt;, with additional one-to-many
references from the existing &lt;cite&gt;SecretACL&lt;/cite&gt; and &lt;cite&gt;ContainerACL&lt;/cite&gt; entities
respectively. No initial records or migrations are needed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;The API will be changed to add a ‘groups’ element to the current ACL JSON
message.&lt;/p&gt;
&lt;p&gt;Hence the response from &lt;cite&gt;GET /v1/secrets/{uuid}/acl&lt;/cite&gt; would become:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"read"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
    &lt;span class="s2"&gt;"updated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"2015-05-12T20:08:47.644264"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"created"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"2015-05-12T19:23:44.019168"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"users"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;user_id1&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;user_id2&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="o"&gt;.....&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s2"&gt;"groups"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;group_id1&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;group_id2&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="o"&gt;.....&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s2"&gt;"project-access"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;access&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;flag&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The following sentence is proposed to be added to the description for the
&lt;cite&gt;PUT /v1/secrets/{uuid}/acl&lt;/cite&gt; call:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;To delete existing groups from an ACL definition, pass an empty list [] for
&lt;cite&gt;groups&lt;/cite&gt;.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Also the following row is proposed added to the &lt;cite&gt;Attributes&lt;/cite&gt; section:&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;groups&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;[string]&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;(optional) List of group ids. This needs to
be group ids as returned by Keystone.&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;[]&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Also the following should replace the ‘Body’ element in the ‘Request/Response’
section:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"read"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
    &lt;span class="s2"&gt;"users"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;user_id1&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;user_id2&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="o"&gt;.....&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s2"&gt;"groups"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;group_id1&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;group_id2&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="o"&gt;.....&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s2"&gt;"project-access"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;access&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;flag&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In addition to the secrets resource API changes, the response from
&lt;cite&gt;GET /v1/containers/{uuid}/acl&lt;/cite&gt; would become:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"read"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
    &lt;span class="s2"&gt;"updated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"2015-05-12T20:08:47.644264"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"created"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"2015-05-12T19:23:44.019168"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"users"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;user_id1&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;user_id2&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="o"&gt;.....&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s2"&gt;"groups"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;group_id1&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;group_id2&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="o"&gt;.....&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s2"&gt;"project-access"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;access&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;flag&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The following sentence is proposed to be added to the description for the
&lt;cite&gt;PUT /v1/containers/{uuid}/acl&lt;/cite&gt; call:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;To delete existing groups from an ACL definition, pass an empty list [] for
&lt;cite&gt;groups&lt;/cite&gt;.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;Also the following row is proposed added to the &lt;cite&gt;Attributes&lt;/cite&gt; section:&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Attribute Name&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Description&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Default&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;groups&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;[string]&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;(optional) List of group ids. This needs to
be group ids as returned by Keystone.&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;[]&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Also the following should replace the ‘Body’ element in the ‘Request/Response’
section:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"read"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
    &lt;span class="s2"&gt;"users"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;user_id1&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;user_id2&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="o"&gt;.....&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s2"&gt;"groups"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;group_id1&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;group_id2&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="o"&gt;.....&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s2"&gt;"project-access"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;access&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;flag&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;The proposed change provides another optional mechanism to access secrets and
containers, via a user’s group ID information.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h3&gt;Notifications &amp;amp; Audit Impact&lt;/h3&gt;
&lt;p&gt;No additional auditing beyond that planned for resource access should be
required.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;Support for adding group IDs to the ACL for a secret or container should be
added to the Barbican Python client as well.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;For each retrieve of a secret or container, an additional query for the group
ACL information will be required.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;No configuration is required. Changes should be applied in the sequence
provided in the ‘Work Items’ section.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;TBD&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;The following work sequence is proposed for a zero-down-time deployment:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Create a CR to modify the Sphinx documentation to include the new ‘groups’
API information, marked as ‘Work in Progress’&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a CR to add the data model entities and relationships described in the
‘Data model impact’ section above, ensuring that current state code still
operates correctly after the data model updates are applied&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create CR(s) to add the SQLAlchemy &lt;cite&gt;barbican.model&lt;/cite&gt;’s &lt;cite&gt;models.py&lt;/cite&gt; classes
and relationships to match the above data model changes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create CR(s) to add the new ‘groups’ list to the ‘acls’ controller module
as detailed above, along with unit tests&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add CR(s) to add functional testing as detailed below&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add CR(s) to add ‘groups’ ACL support to the Barbican Python client&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;This blueprint depends on Keystone middleware providing the group ID
information for a authenticated token via the &lt;cite&gt;X-Group-Ids&lt;/cite&gt; HTTP header. A
pending blueprint to add this capability to Keystone is available here [1].&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;The current functional tests for ACL will be augmented to also test out the new
‘groups’ list.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;The current documentation for ACL will be augmented to add the ‘groups’
information as detailed in the ‘API impact’ section above.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] &lt;a class="reference external" href="https://review.openstack.org/#/c/188564/"&gt;https://review.openstack.org/#/c/188564/&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Fri, 12 Jun 2015 00:00:00 </pubDate></item><item><title>Allow Admins to add CAs</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/liberty/add-cas.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/add-cas"&gt;https://blueprints.launchpad.net/barbican/+spec/add-cas&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;In Kilo, code was added to allow clients to select a back-end CA server
by specifying a Barbican defined ca_id.  These ca_ids can be queried by
doing a GET against the /cas interface.&lt;/p&gt;
&lt;p&gt;In addition, it is now possible for a project admin to associate a set of CAs
with a project, and to define a preferred (or default) CA in case a CA is not
explicitly requested.  All this amounts to the ability for project admins to
constrain project clients to specific CAs.&lt;/p&gt;
&lt;p&gt;It is now time to take the next step.  Dogtag has implemented the ability to
create back-end subordinate CA’s on the fly.  We need to expose this
functionality to project admins, so that they will be able to create project
specific CAs.  This would allow all certificates issued to clients in the
project to be scoped to the project only.&lt;/p&gt;
&lt;p&gt;This project specific scoping improves security by isolating clients, and gives
project admins greater control over their certificates.  Essentially, it is
PKI-as-a-service.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;section id="creating-a-ca"&gt;
&lt;h3&gt;Creating a CA&lt;/h3&gt;
&lt;p&gt;Most of the infrastructure we need is already present.  We will need to add
a POST /cas call to request the creation of a new CA.  This call will be
restricted to project admins.  This call will require at least three parameters:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;subject DN for the new CA signing certificate.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;name or handle for the new CA&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;parent_ca_ref - the reference of the CA to which this CA should be subordinate.
That is, the CA that will issue the new CA’s signing certificate.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Additional parameters may be required to request specific attributes on the
subordinate CA’s signing certificate.  These are currently not exposed in
Dogtag, and therefore will not be part of the initial implementation.&lt;/p&gt;
&lt;p&gt;Two new methods will be added to the CertificateManager interface.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;supports_create_ca() - which will be called to determine if a given plugin
supports this operation.  A default implementation returning False will be
added to CertificateManager,  Plugins that support this option will have to
override this function.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;create_ca(ca_create_dto) - which would be called to create the subCA,
A default implementation that throws a NotSupported exception would be added
to CertManager so that existing plugins would not need to change.
The relevant parameters would be passed in the ca_create_dto.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Barbican core would select an appropriate CA plugin, and invoke create_ca().
If no plugin is appropriate, a 400 error will be returned.&lt;/p&gt;
&lt;p&gt;Otherwise, once the new subCA is created, the data for that subCA will be
returned to Barbican core, which will add the CA to the CA tables.&lt;/p&gt;
&lt;p&gt;The newly created CA reference will be returned to the client.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="ca-ownership"&gt;
&lt;h3&gt;CA Ownership&lt;/h3&gt;
&lt;p&gt;An additional “owner” field will be added to the CA table.  This field will be
populated with the project_id of the project admin when a CA is created using
the mechanism described above.  Changes will be needed to ensure that this
field is not overwritten when Barbican-core syncs up its CA table with the CA
plugins.&lt;/p&gt;
&lt;p&gt;CAs which have been created through the /cas interface (and therefore owned by
a project) will only be list-able and view-able by members of the owning project.
Moreover, only members of that project will be able to submit certificate orders
to that CA.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="deleting-a-ca"&gt;
&lt;h3&gt;Deleting a CA&lt;/h3&gt;
&lt;p&gt;Only project admins will be able to delete a CA.  The CA must be owned by the
project to be deletable.  To do this, a new REST method DEL /cas/{ca_id} will
be exposed.&lt;/p&gt;
&lt;p&gt;This method would look up the necessary CA plugin in the CA table, and would
invoke a new delete_ca(plugin_ca_id) call.  This call would make the relevant
call on the back-end CA, which would, amongst other things, revoke the CA
signing cert.&lt;/p&gt;
&lt;p&gt;On success, the CA would be removed from the CA table.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;A new field “owner” will need to be added to the CA table.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;We will need to add some calls to the /cas/ interface.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;POST /cas - create a CA, as described above.  The attributes name, parent_ca_ref
and subject_dn are required, as seen in the example below.&lt;/p&gt;
&lt;div class="highlight-none notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;POST /v1/cas
Headers:
    X-Project-Id: {project_id}

Content:
{
    "name": "Dogtag CA for Project yxz",
    "parent_ca_ref": "https://localhost/v1/cas/{parent_ca_uuid}",
    "subject_dn": "cn=CA Signing Cert for xyz, dc=example.com"
}
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;DEL /cas/{ca_id} - delete a CA, and revoke the CA signing cert, as described&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;above.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Also, GET /cas and GET /cas/{ca_id} will need to be modified (most likely
in the DB query) so “owned CAs” are only accessible by project members.&lt;/p&gt;
&lt;p&gt;Also, a validation will need to be added to the Orders interface to ensure that
owned CA’s that are referenced by the request belong to the requestor’s project.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h3&gt;Notifications &amp;amp; Audit Impact&lt;/h3&gt;
&lt;p&gt;Make sure that all the actions above are audited as per the auditing spec. [1]&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;python-barbicanclient will need to add methods to perform the new operations.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Minimal.  This is a relatively infrequent admin operation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Migration scripts will need to be run on already existing deployments to add
the new “owner” field.  The owner field will be nullable, so that the code will
handle cases with/without owners.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Plugin developers should not need to make any changes, unless they want to
support the new methods.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;Assignee(s)&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;alee-3&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Update the CAs and Certificates API documentation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write the functional tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the new “owner” field and migration scripts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the new REST API and internal Barbican core logic.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the Dogtag implementation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;The current unit and functional tests will also be modified to reflect these
changes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;This is a new feature that will need to be documented.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Auditing spec &lt;a class="reference external" href="https://review.openstack.org/#/c/159938/"&gt;https://review.openstack.org/#/c/159938/&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description><pubDate>Mon, 01 Jun 2015 00:00:00 </pubDate></item><item><title>Add Transport Cert Reference</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/liberty/add-transport-cert-ref.html</link><description>

&lt;p&gt;Launchpad blueprint:
&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/add-transport-cert-ref"&gt;https://blueprints.launchpad.net/barbican/+spec/add-transport-cert-ref&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;Transport keys are used to ensure that the secret is pre-encrypted in such
a way that only the client and the back-end store can decrypt the secret.&lt;/p&gt;
&lt;p&gt;This is for users which do not trust Barbican, but do trust the back-end
secret store. Alternatively, clients that are required by FIPS or Common Criteria
(CC) requirements only to use CC certified components may be able to argue for
being able to use Barbican if the secrets remain opaque in transit through
Barbican to their final storage back-ends.&lt;/p&gt;
&lt;p&gt;Currently, the client gets the transport key from Barbican. But if the client
does not trust Barbican, this is a potential vulnerability. We need to add the
ability for the client to retrieve the transport key from the back-end store
directly.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;The change here is straightforward.  Instead of only returning the transport
certificate as a result of the GET /transportkeys/{key_id} call, we will also
return a reference to the transport key in the header (TRANSPORT_KEY_URL)
This reference will be provided by the plugin, and should be a link to a trusted
location where the transport cert could be retrieved.  In practice, this would
most likely be an HTTPS connection to the backend secret store.&lt;/p&gt;
&lt;p&gt;Internally, what this means is that the get_transport_key() method in the
secret_store interface would be modified to return a dict containing both the
value of the transport key and an external URL.  We would use this dict to fill
in the contents and header of the response.&lt;/p&gt;
&lt;p&gt;As this method already has a None default configuration, this change should not
require any changes in existing plugins.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;This is a trivial change that makes the transport key story more complete.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;A new field will be added to the header in the response to GET /transportkeys/{key_id}
as described above.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;Makes transport keys more secure.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;The client would need to decide whether to accept the value of the transport
cert as returned by Barbican, or to retrieve the value from the provided URL.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;alee&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;The server side changes can likely be done in a single CR.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Client side changes.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit and functional tests will need to be written.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Docs on transport key use will need to be written and updated.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Mon, 01 Jun 2015 00:00:00 </pubDate></item><item><title>Add Crypto/HSM MKEK Rotation and Migration Support (Lightweight)</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/liberty/add-crypto-mkek-rotation-support-lightweight.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/add-crypto-mkek-rotation-support-lightweight"&gt;https://blueprints.launchpad.net/barbican/+spec/add-crypto-mkek-rotation-support-lightweight&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Currently Barbican has no means to migrate secrets encrypted with a
crypto/HSM-style plugin to a new master key encryption key (MKEK) and its
associated wrapped project KEKs. This blueprint proposes adding a new Barbican
utility that supports completing the rotation process by rewrapping the project
KEKs with the new MKEK. Note that unlike the similarly-named blueprint at [1],
this blueprint does &lt;em&gt;not&lt;/em&gt; call for re-encrypting secrets and is therefore a
‘lightweight’ alternative to that blueprint.&lt;/p&gt;
&lt;p&gt;Comparing the two approaches, this lightweight approach just rotates
the MEKs and rewraps the project KEKs, leaving each secret’s encrypted data
unchanged. The other blueprint rotates the MKEKs, project KEKs and the
encrypted secret information.&lt;/p&gt;
&lt;p&gt;Thus this blueprint has a less thorough rotation process for secrets which
could increase the chances of decrypting the secret’s encrypted data. The
likelihood of such an attack is expected to be small however. After all, MKEKs
are infrequently rotated due to their low probability of being guessed or
compromised. This blueprint’s less thorough approach is expected to be less
process intensive and execute faster when there are many secrets stored in the
database.&lt;/p&gt;
&lt;p&gt;Similar to the other blueprint, this utility would be started after deployers,
out of band:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;generate new MKEK and HMAC signing keys with a binding to new labels, and
then&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Replicate these keys to other HSMs that may be in the high availability (HA)
group, and then&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update Barbican’s config file to reference these new labels, and finally&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Restart the Barbican nodes.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The proposed utility would then rewrap the project KEKs with the new MKEKs,
updating the associated project KEK records with the new wrapped project KEKs.
Note that only HSM/crypto-style plugins rotations are proposed for this
blueprint.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;When a secret is stored in Barbican using the crypto-style plugin, a
&lt;cite&gt;KEKDatum&lt;/cite&gt; entity (from &lt;cite&gt;barbican.model.models&lt;/cite&gt;) is retrieved for the secret’s
project. If no such entities are found for this project, then the following
steps occur:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;A new &lt;cite&gt;KEKDatum&lt;/cite&gt; entity is created for the project and the specific crypto-
style plugin with status of &lt;cite&gt;ACTIVE&lt;/cite&gt;. The &lt;cite&gt;ACTIVE&lt;/cite&gt; status indicates that
this entity should be used for secret encryptions from then on.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;cite&gt;bind_kek_metadata()&lt;/cite&gt; method is invoked on the crypto plugin. The plugin
then creates a project-level KEK that will be used to encrypt new secrets
for that project. For the PKCS11 HSM plugin, this is the project KEK that is
wrapped/encrypted by the MKEK.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Information about this project-level KEK is then added to &lt;cite&gt;plugin_meta&lt;/cite&gt;
attribute of the new &lt;cite&gt;KEKDatum&lt;/cite&gt; entity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When a secret is finally stored, it has a &lt;cite&gt;Secret&lt;/cite&gt; entity created for it to
hold metadata, and also an associated &lt;cite&gt;EncryptedDatum&lt;/cite&gt; entity that holds
both the encrypted cypher text for the secret, and a reference to the
project-level &lt;cite&gt;KEKDatum&lt;/cite&gt; record.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Thereafter, new secrets that need to be encrypted for this same project
will used this &lt;cite&gt;KEKDatum&lt;/cite&gt; entity, with no further attempts made to generate
a new entity.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Hence the &lt;cite&gt;KEKDatum&lt;/cite&gt; entity is associated with project-level KEKs, which in
turn are associated with a single MKEK in the HSM. As rotation involves
creating a new MKEK (but not the project KEKs for this lightweight version),
the &lt;cite&gt;KEKDatum&lt;/cite&gt; entity needs to be updated per project to rewrap/encrypt the
project KEK it contains.&lt;/p&gt;
&lt;p&gt;Unlike the more stringent key rotation blueprint, no other steps are needed.
The secrets, there UUIDs and their associated encrypted data, do not need to
change at all, which should speed the overall migration process.&lt;/p&gt;
&lt;p&gt;A requirement is that this utility be resilient, allowing for the utility to
be re-run if it fails midway.&lt;/p&gt;
&lt;p&gt;This blueprint details an approach to rewrap existing project KEKs with a
new MKEK.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;This blueprint proposes the following steps be taken to complete the KEK
rotation and migration effort:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Out of band to Barbican (so by deployers), new MKEK and HMAC keys are
created in the HSM, with new unique labels. For high availability
configurations such keys must be replicated across all HSMs in the cluster.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For each API and worker node in the network, update their
&lt;cite&gt;/etc/barbican/barbican-api.conf&lt;/cite&gt; files’ &lt;cite&gt;mkek_label&lt;/cite&gt; and &lt;cite&gt;hmac_label&lt;/cite&gt;
attributes with the new unique labels generated above. Note that once
Barbican is restarted, secrets added to new project-IDs will start to use
the new MKEK to wrap their new project KEKs. Existing secrets will still
utilize the old MKEK though hence the need for the new utility.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Restart the API and worker nodes. Barbican should be running normally at
this point, with the following utility-based steps occurring while Barbican
operates.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Via a new utility proposed in this blueprint, query for all &lt;cite&gt;KEKDatum&lt;/cite&gt;
entities for a specified crypto-style plugin class
(e.g. &lt;cite&gt;barbican.plugin.crypto.simple_crypto.SimpleCryptoPlugin&lt;/cite&gt;). These
wrapped-project KEKs need to be rewrapped with the new MKEK.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For each &lt;cite&gt;KEKDatum&lt;/cite&gt; entity, invoke a new method on the crypto-style
plugin contract (defined in &lt;cite&gt;barbican.plugin.crypto.crypto.py&lt;/cite&gt;) called
‘rewrap_project_kek()’, which takes the entity as input and updates it with
the rewrapped project KEK. The plugin would need to load the wrapped
project KEK into the HSM, decrypt it with the old MKEK, encrypt it with the
new MKEK, and then return the new wrapped project KEK (but still containing
the original project KEK).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;cite&gt;KEKDatum&lt;/cite&gt; entity above would then be updated with the new wrapped
project KEK information. Since this is an in-place update, the secrets
associated with this entity do not have to be updated at all, unlike [1].&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Info log the UUID of the migrated &lt;cite&gt;KEKDatum&lt;/cite&gt; entity to produce a record of
the migration.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The proposed utility would be implemented as a Python &lt;cite&gt;barbican.cmd&lt;/cite&gt; script
and added as a &lt;cite&gt;pbr&lt;/cite&gt; entry point in the &lt;cite&gt;setup.cfg&lt;/cite&gt; file, and hence available
as a callable command once Barbican is deployed.&lt;/p&gt;
&lt;p&gt;To preserve data integrity steps 5 and 6 should be performed in a database
transaction.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;See the more heavy-weight alternative approach to key rotation at [1].&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;No data model or repository changes are needed for the proposed solution. Data
migrations will be required as detailed in the Proposed Change section above.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;The proposed solution completes necessary key rotation processes by rewrapping
project KEKs used to encrypt secrets. There are improbable but possible data
loss risks with the proposed approach however, since project KEKs encrypted
with old MKEKs are replaced with these same project KEKs encrypted with the new
MKEKs. If the database update transaction fails and corrupts this record (very
unlikely with ACID compliant databases, but possible), decryption would fail
for all secrets derived from the failed project KEK. However, since these
wrapped project KEKs do not change often (on the order of the MKEK rotation
schedule) recovery from database backups is very likely, thus mitigating this
risk.&lt;/p&gt;
&lt;p&gt;Also, if the MKEK is compromised &lt;em&gt;and&lt;/em&gt; if the attacker has access to the
database backups for secrets they can then decrypt them by first unwrapping
the project KEKs. Deployers should be mindful of this and securely store
backups.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h3&gt;Notifications &amp;amp; Audit Impact&lt;/h3&gt;
&lt;p&gt;A log of each &lt;cite&gt;KEKDatum&lt;/cite&gt; entity migrated is produced by the proposed utility,
which could be used to prove to auditors that a migration/rotation occurred.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;The proposed utility could take significant time to process if there are many
project-IDs to migrate, and thus it would represent a load on the HSM to
re-wrap the project KEKs, impacting normal Barbican operations. This utility
would be called quite infrequently however (maybe 1 to 4 times a year). Since
there are fewer project IDs/KEKs then secrets, this utility would be more
performant than the ‘all secrets’ migration proposed in [1].&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;The proposed utility would be executed as a new executable command available
after deployment Barbican. The proposed changes would not require updates to
the configuration file schema, but would require updates to provide new
MKEK and HMAC key labels as detailed above.&lt;/p&gt;
&lt;p&gt;Also, if the MKEK is compromised &lt;em&gt;and&lt;/em&gt; if the attacker has access to the
database backups for secrets they can then decrypt them by first unwrapping
the project KEKs. Deployers should be mindful of this and securely store
backups.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;TBD&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;The proposed work items are:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Create a Python command script to implement the steps in the Proposed
Change section.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add unit testing to cover the new code lines.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add integration unit test that, using the default &lt;cite&gt;simple_crypto.py&lt;/cite&gt; plugin
and an in-memory SQLite database, first creates a few known secrets with the
default MEK in the config file, and then modifies this MEK, and then
executes the migration script logic. The secrets should be decrypted and
verified for accuracy. The &lt;cite&gt;KEKDatum&lt;/cite&gt; entities should have their
&lt;cite&gt;updated_at&lt;/cite&gt; dates updated. The secrets should again be decrypted and
verified for accuracy, which proves the migration of all secrets to the
updated &lt;cite&gt;KEKDatum&lt;/cite&gt; record occurred successfully.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Document the overall key rotation and migration process, including the usage
of the new migration utility.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;No DevStack functional tests are expected at this time. Once an HSM gate job is
added, a future blueprint add tests will be added.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;The last work item details the required documentation.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] &lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/add-crypto-mkek-rotation-support"&gt;https://blueprints.launchpad.net/barbican/+spec/add-crypto-mkek-rotation-support&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Fri, 08 May 2015 00:00:00 </pubDate></item><item><title>Remove the tenant-secret association table</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/liberty/data-remove-tenant-secret-assoc.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/data-remove-tenant-secret-assoc"&gt;https://blueprints.launchpad.net/barbican/+spec/data-remove-tenant-secret-assoc&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Currently all secrets stored in Barbican are indirectly associated with
Keystone ‘projects’ (formerly known as ‘tenants’) via a tenant-secret
association table. This association was added early in Barbican’s lifecycle,
when it seemed that such an association would aid in retrieving different
components of grouped secrets with different RBAC behaviors. However, recent
discussions with OpenStack projects have indicated that this feature would be
better implemented in a different way. Hence this association adds an
additional join on selects with no benefit, and therefore should be removed.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Secrets in Barbican are indirectly related to Keystone ‘projects’ via a
TenantSecret association table. This association is not utilized for any
features in Barbican currently but was envisioned to allow multiple ‘projects’
to access the same secret with different access privileges. The team has since
had numerous discussions with OpenStack projects that wish to integrate with
Barbican, and access control could either be accomplished via Keystone Trusts,
or else via ‘user’ and ‘project’ level policy based on metadata configured at
the secret level (see blueprint at &lt;a class="footnote-reference brackets" href="#id2" id="id1" role="doc-noteref"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;1&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/a&gt;)&lt;/p&gt;
&lt;aside class="footnote-list brackets"&gt;
&lt;aside class="footnote brackets" id="id2" role="doc-footnote"&gt;
&lt;span class="label"&gt;&lt;span class="fn-bracket"&gt;[&lt;/span&gt;&lt;a role="doc-backlink" href="#id1"&gt;1&lt;/a&gt;&lt;span class="fn-bracket"&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/127353/"&gt;https://review.openstack.org/#/c/127353/&lt;/a&gt;&lt;/p&gt;
&lt;/aside&gt;
&lt;/aside&gt;
&lt;p&gt;Hence the TenantSecret association is not required for any envisioned Barbican
use cases and therefore represents a wasteful join for all secret selects.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;This blueprint proposes removing the unused TenantSecret association.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;The TenantSecret table would be removed, along with associated SQLAlchemy
models and repository queries. This schema modification would require a
non-trivial migration for zero downtime, as detailed in the ‘Work Items’
section below.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h3&gt;Notifications &amp;amp; Audit Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Removing the TenantSecret association removes one join from secret-related
queries, and removes Python code needed to create the SQLAlchemy TenantSecret
model. Hence performance and code readability should be improved.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Migration scripts would need to be run on already existing deployments. There
will be no other impact otherwise.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;Assignee(s)&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;john-wood-w&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;The schema modification called for would need to be phased in to avoid breaking
existing deployments with secrets stored using the current TenantSecret
associations.&lt;/p&gt;
&lt;p&gt;The first phase would add the new and initially nullable ‘tenant_id’ FK
relationship to the secret entity, with all new secrets added setting this FK,
and still adding the TenantSecret relationships (until older versions are
rotated out). Secret retrievals would first attempt the simple query by FK, and
fallback to the current TenantSecret join. The following mods would be needed::
* models.py: Add a ‘secrets_assoc’ relationship in the Tenant model class to
the secrets model, similar to the ‘Container’ relationship. To the Secret
model, add a ‘tenant_id’ FK reference similar to the Container model’s
‘tenant_id’ FK reference, but with nullable=True.
* repositories.py: In the SecretRepo
repository class add a query for secrets without the TenantSecret join, but on
errors revert to the existing TenantSecret join query.
* plugin/resources.py: Add setting the new ‘tenant_id’ FK on secrets to the
‘_save_secret()’ function.
* store_crypto.py: Add setting the new ‘tenant_id’ FK on secrets to the
‘_store_secret_and_datum()’ function.&lt;/p&gt;
&lt;p&gt;The second phase would provide an Alembic migration script to set the
‘tenant_id’ FK on all secrets that don’t already have it set. The ‘tenant_id’
FK would then be set as nullable=False.&lt;/p&gt;
&lt;p&gt;The third phase would remove all logic related to the TenantSecret
relationship. The following mods would be needed::
* models.py: Remove TenantSecret SQLAlchemy model class.
* repositories.py: Remove TenantSecret joins from queries in the SecretRepo
repository class. Remove the ProjectSecretRepo repository class. Remove
‘ProjectSecretRepo’ from the Repositories class. Remove the
‘get_project_secret_repository’ function.
* plugin/resources.py: Remove ‘new_assoc’ lines from the ‘_save_secret()’’
function.
* store_crypto.py: Remove ‘new_assoc’ lines from the
‘_store_secret_and_datum()’ function.
* api/test_resources.py: Remove ‘project_secret_repo’ lines from the
‘_test_should_add_new_secret_metadata_without_payload’ test method.
* test_repositories.py: Remove all ‘TenantSecret’ related lines.
* test_store_crypto.py: Remove all ‘project_secret_repo’ lines.&lt;/p&gt;
&lt;p&gt;The fourth phase would provide an Alembic migration script to remove the
TenantSecret relationship from all secrets, and to then drop the TenantSecret
table altogether.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;The current unit tests will also be modified to have this change reflected upon
them. Migration testing across the different phases would be needed, at least
manually.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 07 May 2015 00:00:00 </pubDate></item><item><title>Define Content Types for API and Secret Store</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/kilo/content-type.html</link><description>

&lt;p&gt;The current implementation of Barbican is ambiguous to end users and developers
as to the encoding that should be used to input new secrets and the encoding of
secrets that are returned. This spec aims to define the encoding specifications
for each of the secret types and define all of the secret types. The encoding
specifications will allow end users and developers to know how to handle
the secrets.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;The biggest problem that currently exists is that data returned from the API
and SecretStores is not clearly defined. An example would be public keys. When
an end user requests a public key there were many options for how to return
that data. One was to return just the public key (not the certificate) as a
Base64 encoded string, but the question still remained of what was the format
of the binary representing the key. However, most interpreted this to mean
return a certificate. Then the question was raised as to how to return the
certificate. Should it be PEM or DER format. Clearly there were lots of
assumptions and unanswered questions.&lt;/p&gt;
&lt;p&gt;There are two problems above. One is that we need to clearly define all of the
possible secret types. This will eliminate the public key versus certificate
issue. The other problem is that we need to define the encoding standard
options for each type of secret. Then end users and SecretStore developers will
know that if they have a secret of type X then it has an encoding of type Y.&lt;/p&gt;
&lt;p&gt;The scope of this blueprint is limited to unencrypted secrets. In particular
this spec does not cover the encoding standards for keys wrapped with a
transport key nor does it cover the encoding scheme for private keys that are
encrypted with a passphrase.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;section id="define-all-secret-types"&gt;
&lt;h3&gt;Define All Secret Types&lt;/h3&gt;
&lt;p&gt;The first change will be to modify the SecretType class to include all of the
possible secret types. The SecretType class represents an enum, and the
currently defined values are symmetric, public, and private.&lt;/p&gt;
&lt;p&gt;This spec proposes adding the types certificate, passphrase, and opaque data.
The certificate type would represent X.509 certificates. The current spec would
not support PGP certificates, but mostly because I do not know much about them.
If support is needed then we can work through that. More than likely I think
that if certificates other than X509 are to be supported then a subtype enum
for certificates should be created to indicate the type, X.509, PGP, etc. That
would be for another spec, and this one will assume only X.509 certificates.&lt;/p&gt;
&lt;p&gt;The opaque data type would represent an unknown blob of data. This is reserved
for types that are not keys or certificates. Barbican will not be able to
understand any of the qualities about the data. It will simply be a blob.
This is the type that would be used for secret data like IVs.&lt;/p&gt;
&lt;p&gt;Here is a listing of the proposed secret types&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;symmetric key&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;public key&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;private key&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;passphrase&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;certificate&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;opaque data&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="content-encoding-for-each-secret-type"&gt;
&lt;h3&gt;Content Encoding for Each Secret Type&lt;/h3&gt;
&lt;p&gt;The second change will be to define the content encoding for each of the secret
types. The types and proposed encodings are below.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;symmetric key - Base64 encoding of byte array in network byte order&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;public key - Base64 encoding of DER-encoded SubjectPublicKeyInfo structure as
defined by X.509 RFC 5280 with PEM header and footer&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;private key - Base64 encoding of PKCS#8 structures with PEM header and footer&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;passphrase - text with utf-8 encoding&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;certificate - Base64 encoding of DER-encoded ASN.1 X.509 structure with PEM
header and footer&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;opaque data - Base64 encoding of byte array in network byte order&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The formats for the public and private keys were chosen based on their
popularity. The public key format of SubjectPublicKeyInfo was chosen because
that is the default format for public keys by openssl and Java. Plus it is a
part of the common X.509 standard.&lt;/p&gt;
&lt;p&gt;The private key format of PKCS#8 is the default encoding for Java. The default
encoding for generating new private keys in openssl is not PKCS#8. The default
encoding in openssl is referred to as the “traditional” format in openssl
documentation. The term traditional is ambiguous. It is in fact the plain
private key structure, so for RSA it is the private key structure as defined in
PKCS#1. This is a subset of the PKCS#8 structure.&lt;/p&gt;
&lt;p&gt;The openssl library does support using PKCS#8 keys, and this does not require
changing any command line options. The library automatically detects the
encoding and uses the key if it is in PKCS#8 encoding or openssl “traditional”
encoding. Because of this and the ambiguity of the term “traditional” I
recommend using the PKCS#8 format. It is clear to developers and users of the
expected format.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;One alternative would be to leave everything as is. The downsides of this
approach are identified above.&lt;/p&gt;
&lt;p&gt;There may be other ways to represent the keys. We could define our own
structures instead of using ASN.1. I chose to use ASN.1 and other standards
because I think they are widely adopted and accepted. I think exporting keys
from existing applications makes the choices the best option.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data Model Impact&lt;/h3&gt;
&lt;p&gt;The only expected change is to modify the Secret entity to include a type
column. The type column will be one of the predefined secret types of symmetric
key, public key, private key, passphrase, certificate, or opaque data.&lt;/p&gt;
&lt;p&gt;The secret stores currently expect an array of bytes that are Base64 encoded,
so I do not anticipate changing anything with the secret store classes. The
only difference now is that secret stores will have more insight as to the
format of those bytes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API Impact&lt;/h3&gt;
&lt;p&gt;The API for storing keys requires setting the payload_content_type and
payload_content_encoding for the secret. For each type of secret there needs to
a set of acceptable payload_content_type and payload_content_encoding values
that are acceptable.&lt;/p&gt;
&lt;p&gt;This also means that the secret type should be supplied as a new parameter.
This was something that was missing before. The current implementation can only
infer the secret type for symmetric keys that are uploaded because it can use
the algorithm to determine that. The algorithm is not enough to infer the
secret type for asymmetric keys since it could be a public or private key.
Therefore a secret type should be provided. The current implementation
currently stores them as unknown.&lt;/p&gt;
&lt;p&gt;The table below lists the acceptable content types and content encoding values
for each type of secret. Each pair is represented as (payload_content_type,
payload_content_encoding). API calls that do not receive data in the specified
encoding will receive a 406 error code response.&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;symmetric key (application/octet-stream, Base64)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;public key (application/octet-stream, Base64)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;private key (application/pkcs8, Base64)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;passphrase (text/plain, utf-8)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;certificate (application/pkix-cert, Base64)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;opaque data (application/octet-stream, Base64), (text/plain, NULL)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="supporting-backwords-compatability"&gt;
&lt;h4&gt;Supporting Backwords Compatability&lt;/h4&gt;
&lt;p&gt;The new parameter for secret type will be an optional parameter to support
backwards compatability. If it is not supplied then the key type opaque data
will be used. Opaque data will be the only secret type to support multiple
acceptable content types. This was chosen to support backwards compatability.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="secret-store-impact"&gt;
&lt;h4&gt;Secret Store Impact&lt;/h4&gt;
&lt;p&gt;The API content type and content encodings are defined above. However, the
format of keys passed to the secret stores needs to be defined as well. The
keys are passed from Barbican Core to the secret store using the SecretDTO
object.:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;+-------------+&lt;/span&gt;       &lt;span class="o"&gt;+-------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;SecretType&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;KeySpec&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-------------+&lt;/span&gt;       &lt;span class="o"&gt;+-------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;SYMMETRIC&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;algorithm&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;PUBLIC&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;bit_length&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;PRIVATE&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;passphrase&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;CERTIFICATE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;+-------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;OPAQUE&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;        &lt;span class="o"&gt;^&lt;/span&gt;
&lt;span class="o"&gt;+-------------+&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;
           &lt;span class="o"&gt;^&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;has&lt;/span&gt;
           &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;has&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;
           &lt;span class="o"&gt;|&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="o"&gt;+---------------+&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;SecretDTO&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="o"&gt;+---------------+&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;          &lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;secret&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;key_spec&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;content_type&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;transport_key&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="o"&gt;+---------------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The current SecretDTO has a content_type property and a secret property. The
secret property is a Python string that is the Base64 encoding of the bytes
that represent the secret. The content_type is the content_type parameter
received from the API call. Since we are defining a single encoding for each
SecretType of a SecretDTO then this parameter can be removed. The encodings
will be the same as that of the API except that opaque data will be as a Base64
encoding of the bytes and not allowed to be text/plain.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h3&gt;Notifications &amp;amp; Audit Impact&lt;/h3&gt;
&lt;p&gt;The ability to audit the types of keys that are managed by Barbican could be
added.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other End User Impact&lt;/h3&gt;
&lt;p&gt;We can validate secrets before they are stored to validate the structures are
correct. This will help users by preventing them from uploading secrets of a
specific type that are not formatted correctly.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None, unless validation is done in which case there will be minor overhead to
validate the secret structures.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Secret store developers will need to possibly modify their code to return
secrets in the specified format.&lt;/p&gt;
&lt;p&gt;The Barbican client will need to be updated to utilize the encodings and add
the secret type parameter.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Nathan Reller (rellerreller)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Add secret type&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Modify the API to accept a new secret_type parameter. The secret_type must be
one of the predefined types, so a validator should be added for that. If not
provided then use opaque data unless symmetric algorithm is provided.&lt;/p&gt;
&lt;p&gt;Modify barbican.plugin.resources to create a SecretDTO with the appropriate
secret type.&lt;/p&gt;
&lt;ol class="arabic simple" start="2"&gt;
&lt;li&gt;&lt;p&gt;Add basic secret type validators&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Add some basic validators that ensure the secrets passed to the API are
formatted correctly. This first check would simply be to validate PEM headers.
For example, when passing an RSA key this would check that the proper PEM
header is included.&lt;/p&gt;
&lt;p&gt;This step will _not_ do a deep inspection of the secrets passed to Barbican. A
deep inspection would validate each of the structures to make sure the correct
structures are received. For RSA public keys this would check that it contains
a modulus and public exponent.&lt;/p&gt;
&lt;ol class="arabic simple" start="3"&gt;
&lt;li&gt;&lt;p&gt;Update API documentation&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Update the documentation to include notes on the expected encodings and include
documentation on the new secret type argument for posting secrets.&lt;/p&gt;
&lt;ol class="arabic simple" start="4"&gt;
&lt;li&gt;&lt;p&gt;Update barbicanclient&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Update barbicanclient to take advantage of the new secret types and comply with
the API changes.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Add validator tests to verify the API is correctly parsing the new secret type
and catching the instances where the incorrect encoding is used for keys passed
to the API.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Update the API documentation to include information on the new secret type API
parameter and the encodings for each of the secret types.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;PKCS#8 -&lt;a class="reference external" href="https://tools.ietf.org/html/rfc5958"&gt;https://tools.ietf.org/html/rfc5958&lt;/a&gt;
X.509 - &lt;a class="reference external" href="https://tools.ietf.org/html/rfc5280"&gt;https://tools.ietf.org/html/rfc5280&lt;/a&gt;
Java Key - &lt;a class="reference external" href="http://docs.oracle.com/javase/7/docs/api/java/security/Key.html"&gt;http://docs.oracle.com/javase/7/docs/api/java/security/Key.html&lt;/a&gt;
openssl to pkcs8 - &lt;a class="reference external" href="https://www.openssl.org/docs/apps/pkcs8.html"&gt;https://www.openssl.org/docs/apps/pkcs8.html&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Mon, 05 Jan 2015 00:00:00 </pubDate></item><item><title>Add ability for functional tests to run as different users</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/kilo/add-run-as-for-functional-tests.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/add-run-as-for-functional-tests"&gt;https://blueprints.launchpad.net/barbican/+spec/add-run-as-for-functional-tests&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Currently all Barbican functional tests run under the same userid.
This blueprint adds the ability for a Barbican functional test to run
under a different userid from that default.  This is needed to
support the ability to execute tests in parallel and ensure that the
underlying system state doesn’t change as a result of other concurrently
executing tests.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Today all Barbican functional tests run under the same user.
Since these tests run in parallel then any assumptions about the
underlying system state are invalid - for example, a test for paging
secrets could fail if another tests does secret operations in parallel.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The proposed change not only solves this problem, but also provides a
generalized way to run tests in an isolated manner, under their own
userid.&lt;/p&gt;
&lt;p&gt;The first step involves determining which test(s) need to run as a non-default
user.  This is done at testcase creation time, by the testcase author.&lt;/p&gt;
&lt;p&gt;Next the testcase author will create their test within class that extends
a proposed new class
(functionaltests.api.base.DynamicUserTestCase) which extends the existing
functionaltests.api.base.TestCase to indicate that the test(s) should not
be run under the default user, but rather under a new user.&lt;/p&gt;
&lt;p&gt;The user name, password, and tenant name for this new user are derived from
settings in barbican’s etc/dev_tempest.conf file.  Under a new
[key-manager] section are three new settings:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;dynamic_user_userid_prefix&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;testuser_&lt;/span&gt;
&lt;span class="n"&gt;dynamic_user_password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;topsecret&lt;/span&gt;
&lt;span class="n"&gt;dynamic_user_tenant_prefix&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;testtenant_&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;As part of each invocation of the test, the oslotest fixture for the
DynamicUserTestCase setUp() code will:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;generate a new, unique user
- new userid = dynamic_user_userid_prexfix concatenated with a UUID
- new password = value of dynamic_user_password
- new tenant name = value of dynamic_user_tenant_name_prefix
concatenated with the same UUID that was used for the new userid.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;login that user&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;run the test&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;logout and delete the user we created above&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Next the test itself will be run as usual.&lt;/p&gt;
&lt;p&gt;When the test completes, the oslotest fixture tearDown() code will
logout and delete the new user.&lt;/p&gt;
&lt;p&gt;The components of barbican that will need to be updated to support
this new function are:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;new class added to functionaltests.api.base.py called
DynamicUserTestCase that will create and login a new user
for use with that testcase.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DynamicUserTestCase.setup() will create and login the new user&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DynamicUserTestCase.tearDown() will delete that user&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Support functions in functionaltests.api.base.TestCase to talk to
the auth provider for userid creation, login and deletion.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;One alternative that was discussed was to create a new decorator
called @run_as for which could be used for any test, not requiring
a new subclass of Testcase.&lt;/p&gt;
&lt;p&gt;We rejected that approach for several reasons:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Tests requiring this decorator generally have some other focus
of their testing.  For example, pagination tests for secrets
have their focus on pagination, not on secrets.  It makes sense
that these tests aren’t grouped in the same class as secrets, but
rather in their own subclass.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adding decorators where they aren’t necessarily the best mechanism
can lead to confusing and hard to debug code.  Care should be taken
to ensure that a decorator is really the best way to implement.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;No data model impact.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;No REST API impact.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;This change allows dynamic user creation and deletion on a per-testcase
basis.  It also allows a testcase to specify an existing user to run
under.  There are no changes to any API as all of these updates are
focused under the functionaltests and do not affect the Barbican API.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h3&gt;Notifications &amp;amp; Audit Impact&lt;/h3&gt;
&lt;p&gt;No notification/audit impacts for this change.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;The test logging will show the user id that each test runs under in the
test logs.  They are not part of the API, but could be useful for problem
determination and debugging.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;The only performance impact of this CR is on the functionaltests path.
It has no effect on the product’s performance.&lt;/p&gt;
&lt;p&gt;Tests that request a different user will incur additional pathlength to:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;create and login the user (before the test runs)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;delete the user (after the test completes)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Need to ensure that the fields for dynamic user creation in
etc/dev_tempest.conf are acceptable for the tester.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Developers adding functional tests can choose to have those tests run
under a different userid, if they desire.  Otherwise, all functional
tests will run under the default user.&lt;/p&gt;
&lt;p&gt;Unit tests are NOT impacted by this change.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;sheyman (hockeynut)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;Upon approval of this blueprint we will code and post for review the
implementation of the new class as well as the supporting code
in the utilities and fixtures.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;This function depends on keystone for the user and tenant creation and deletion
API.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;This code is part of the functional testing of Barbican and will be exercised
in the devstack gate as well as locally on a developer/tester machine by
running “tox -e functional”&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Currently there is no documentation on how to write Barbican tests (it is an
open story in the Barbican work backlog).  The prose in this blueprint
can be used as a starting point to describe the usage of the
DynamicUserTestCase.&lt;/p&gt;
&lt;p&gt;An important item to cover in the documentation is guidance as to when a test
needs to run as a DynamicUserTestCase.  We should use an example such as:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;test A that creates a large number of secrets, then fetches the list of all
secrets and validates the size of that list against the number created.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;test B that simply creates a new secret.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;If test B runs in the middle of the execution of test A then the secret count
expected by test A will be off by one, and test A will fail.&lt;/p&gt;
&lt;p&gt;However, if test A runs as a different user from test B then there will
be no interference between the two and both tests will pass as expected.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Barbican wiki: &lt;a class="reference external" href="https://wiki.openstack.org/wiki/Barbican"&gt;https://wiki.openstack.org/wiki/Barbican&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Barbican source code: &lt;a class="reference external" href="https://github.com/openstack/barbican"&gt;https://github.com/openstack/barbican&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Barbican functional tests: &lt;a class="reference external" href="https://github.com/openstack/barbican/tree/master/functionaltests"&gt;https://github.com/openstack/barbican/tree/master/functionaltests&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Wed, 19 Nov 2014 00:00:00 </pubDate></item><item><title>Common Certificate API</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/kilo/certificate-order-api.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/certificate-order-api"&gt;https://blueprints.launchpad.net/barbican/+spec/certificate-order-api&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;We currently have a mechanism for enrolling a certificate request by creating
a new order, and passing parameters in the metadata of the order.  Currently,
the parameters in the metadata are passed through to the CA plugin unchanged.
This means that - as long as the parameters passed in match the parameters
expected by a particular back-end, then a  certificate request can be created
for that back-end.&lt;/p&gt;
&lt;p&gt;This diminishes the power of the abstraction though.  A client should not
have to know which CA is served by the Barbican server.  Rather, a client
should be able to request a certificate through a common API, which should be
supported by all known certificate plugins.&lt;/p&gt;
&lt;p&gt;The trick is to define an interface/metadata parameters that would be
supported by most CA’s.  An attempt was made to do this in [1].&lt;/p&gt;
&lt;p&gt;Recently, it was suggested to use RFC 7030 [4], as a standards-based approach
for a common API.  RFC7030 basically proposes an HTTP interface for submitting
CMC (RFC 5272) requests, and receiving the relevant responses.&lt;/p&gt;
&lt;p&gt;RFC 7030 is too different from the current Orders interface and functionality
for us to consider adding for Kilo.&lt;/p&gt;
&lt;p&gt;On the other hand, CMC requests - both simple and full - as defined in
RFC 5272 [2] - have been standards for some time now, and are supported by
most, if not all, Certificate Authorities.  This makes them ideal candidates
for objects in a common set of parameters supported by multiple back-end
CA’s.&lt;/p&gt;
&lt;p&gt;Ideally, the CMC request could be passed intact from barbican core
through the plugin to the backend CA.  The following CA’s are known to support
CMC requests directly: Dogtag, Microsoft CA.&lt;/p&gt;
&lt;p&gt;Even if a CA does not support CMC requests directly, the CMC request provides
a convenient standard-based vechicle for describing all the requested x509
extensions, request data and authentication mechanisms like POP.  These are
things that we do not want to try to re-invent.&lt;/p&gt;
&lt;p&gt;And of course, as simple CMC == PKCS10 - which should be supported by all CAs,
writing a plugin method to support simple CMC requests should be trivial.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;We will continue to use the Orders resource to enroll certificate requests,
and the order metadata to contain the request parameters.  Order requests
can look like this:&lt;/p&gt;
&lt;p&gt;Option 1: Order using a Simple PKI Request (See Section 3.1 in RFC 5272):&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"certificate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"meta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"ca"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"CA identifier (optional, see note in reference [3] below)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"request_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"simple-cmc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"request_data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"base64 encoded simple CMC request (PKCS10)"&lt;/span&gt;
        &lt;span class="s2"&gt;"requestor_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"(optional) string"&lt;/span&gt;
        &lt;span class="s2"&gt;"requestor_email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"(optional) email address - RFC 5322, 5321"&lt;/span&gt;
        &lt;span class="s2"&gt;"requestor_phone"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"(optional) string"&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Option 2: Order using a Full PKI Request (PKCS7, see section 3.2 in RFC 5272):&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"certificate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"meta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"ca"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"CA identifier (optional, see note in reference [3] below)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"request_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"full-cmc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"request_data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"base64 encoded full CMC request (PKCS7)"&lt;/span&gt;
        &lt;span class="s2"&gt;"requestor_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"(optional) string"&lt;/span&gt;
        &lt;span class="s2"&gt;"requestor_email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"(optional) email address - RFC 5322, 5321"&lt;/span&gt;
        &lt;span class="s2"&gt;"requestor_phone"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"(optional) string"&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Option 3: Order using keys already stored in Barbican:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"certificate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"meta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"ca"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"CA identifier (optionali, see note in reference [3] below)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"request_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"stored-key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"public_key_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"barbican UUID for public key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"subject_dn"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"subject DN (RFC1485 [5])"&lt;/span&gt;
        &lt;span class="s2"&gt;"extensions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"base 64 DER encoded ASN.1 values (RFC 5280)"&lt;/span&gt;
        &lt;span class="s2"&gt;"requestor_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"(optional) string"&lt;/span&gt;
        &lt;span class="s2"&gt;"requestor_email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"(optional) email address - RFC 5322, 5321"&lt;/span&gt;
        &lt;span class="s2"&gt;"requestor_phone"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"(optional) string"&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;Extensions&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="n"&gt;defined&lt;/span&gt; &lt;span class="n"&gt;by&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;following&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;RFC&lt;/span&gt; &lt;span class="mi"&gt;5272&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt; &lt;span class="mf"&gt;3.1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;where&lt;/span&gt;
&lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;specific&lt;/span&gt; &lt;span class="n"&gt;ASN&lt;/span&gt;&lt;span class="mf"&gt;.1&lt;/span&gt; &lt;span class="n"&gt;structures&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="n"&gt;extension&lt;/span&gt; &lt;span class="n"&gt;are&lt;/span&gt; &lt;span class="n"&gt;defined&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;RFC&lt;/span&gt; &lt;span class="mi"&gt;5280&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;section&lt;/span&gt; &lt;span class="mf"&gt;4.2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;

&lt;span class="n"&gt;Extensions&lt;/span&gt;  &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;  &lt;span class="n"&gt;SEQUENCE&lt;/span&gt; &lt;span class="n"&gt;SIZE&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MAX&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;OF&lt;/span&gt; &lt;span class="n"&gt;Extension&lt;/span&gt;

&lt;span class="n"&gt;Extension&lt;/span&gt;  &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt;  &lt;span class="n"&gt;SEQUENCE&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="n"&gt;extnID&lt;/span&gt;      &lt;span class="n"&gt;OBJECT&lt;/span&gt; &lt;span class="n"&gt;IDENTIFIER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="n"&gt;critical&lt;/span&gt;    &lt;span class="n"&gt;BOOLEAN&lt;/span&gt; &lt;span class="n"&gt;DEFAULT&lt;/span&gt; &lt;span class="n"&gt;FALSE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="n"&gt;extnValue&lt;/span&gt;   &lt;span class="n"&gt;OCTET&lt;/span&gt; &lt;span class="n"&gt;STRING&lt;/span&gt;
                 &lt;span class="o"&gt;--&lt;/span&gt; &lt;span class="n"&gt;contains&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;DER&lt;/span&gt; &lt;span class="n"&gt;encoding&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;an&lt;/span&gt; &lt;span class="n"&gt;ASN&lt;/span&gt;&lt;span class="mf"&gt;.1&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;
                 &lt;span class="o"&gt;--&lt;/span&gt; &lt;span class="n"&gt;corresponding&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;extension&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="n"&gt;identified&lt;/span&gt;
                 &lt;span class="o"&gt;--&lt;/span&gt; &lt;span class="n"&gt;by&lt;/span&gt; &lt;span class="n"&gt;extnID&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Order 4: Orders using parameters for a specific CA.&lt;/p&gt;
&lt;p&gt;This mechanism is already supported by the existing code.  There is a
blueprint for an API to retrieve the possible parameters from the server [7]:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"certificate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"meta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"ca"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"CA identifier (optional, see note in reference [3] below)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"request_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"custom"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"ca_specific_parameter1"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"ca_specific_parameter2"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"value2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="o"&gt;...&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In the Barbican server, logic will need to be added to differentiate between
these different request types.  For backward compatibility, if request_type
is not provided, then we will assume that it is “custom”.&lt;/p&gt;
&lt;p&gt;On the server, we can add the following logic:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;For Orders 1 and 2, we may be able to validate whether the request_data
is valid PKCS10/ PKCS7. To do this, we could use PyASN.1 to attempt to
decompose the request into the relevant ASN.1 structure, and fail if the
decomposition is unsuccessful.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For Order 3, we should retrieve the relevant public key, create a PKCS10
request using the public key, subject DN and extensions data.  Submit to
backend as a simple CMC request.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For Orders 1,2,3, submit to plugin through new CertPlugin API calls:
issue_simple_cmc_request(), issue_full_cmc_request().&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Plugins will interact with the back-end CA, which presumably will return
PKCS7 full CMC responses.&lt;/p&gt;
&lt;p&gt;The plugin will be responsible for interpreting the response and returning
a ResultDTO object to barbican-core.  Processing would then proceed as
already coded in Barbican-core.&lt;/p&gt;
&lt;p&gt;In order to simplify the plugin code, and to avoid unnecessary duplication
of code, barbican-core will provide some utility functions to parse a
CMCResponse and convert the result into a ResultDTO object.&lt;/p&gt;
&lt;p&gt;The details of this work need not be specified in this spec, but essentially
this involves mapping the CMCStatus field to a Barbican CertificateStatus
values, and extracting certs, intermediates, Query Pending control/ pendInfo
data, and/or error messages as appropriate.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The new and existing certificate request issuance methods
(issue_*_cmc_request, issue_certificate_request) will be provided default
implementations (which would raise NotImplemented exceptions) in case any
plugins have not yet implemented the relevant methods.&lt;/p&gt;
&lt;p&gt;In addition, the supports() on each plugin would need to be modified to
specify whether the plugin supports each certificate issuance method.&lt;/p&gt;
&lt;p&gt;Moreover, the API that identifies the available CAs will also include
information on which methods are supported by each plugin, so that clients
can determine which method to use for a particular CA a priori.  This
information can be extracted from the supports() method.  See [3] for more
information.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note on Certificate Request Updates:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Typically, a CA will not allow a certificate request to be amended once it
has been submitted, with the exception of the optional requestor data.&lt;/p&gt;
&lt;p&gt;For the certificate update API, therefore, I propose the following method:&lt;/p&gt;
&lt;p&gt;PUT /orders/{order_id}:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"certificate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"meta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"requestor_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"(optional) string"&lt;/span&gt;
        &lt;span class="s2"&gt;"requestor_email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"(optional) email address - RFC 5322, 5321"&lt;/span&gt;
        &lt;span class="s2"&gt;"requestor_phone"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"(optional) string"&lt;/span&gt;
     &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This unambiguously specifies the fields that we expect to be able to change
in a certificate request for all request types above.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;One possibility is to implement an API that implements RFC 7030, which is also
an HTTP interface around CMC requests. RFC 7030 expects clients to send CMC
requests to specific URLs, and process CMC responses.&lt;/p&gt;
&lt;p&gt;The main problem with adopting a RFC 7030 interface is that it is very
different from what we have already implemented in Barbican, and we would have
to jettison/rewrite much of the code we already have.  That is not doable in
kilo.&lt;/p&gt;
&lt;p&gt;Some of the workflows are quite different.&lt;/p&gt;
&lt;p&gt;For example, if the cert is pending, there is logic within Barbican to poll
for the certificate until it is approved and issued. Then the certificate
and its intermediates are stored within Barbican for later retrieval.&lt;/p&gt;
&lt;p&gt;For RFC7030, the client needs to handle the polling by decoding the pkcs7-mime
response – which is 202 – and re-submitting the same request until it is
approved.&lt;/p&gt;
&lt;p&gt;Moreover, there is no support for storing the certificate on the server,
and returning things like order_id, secret_id etc. Nor is there support for
amending/ canceling the order.&lt;/p&gt;
&lt;p&gt;Instead of supporting CMC, we could try to define a common API with a basic set
of parameters for different profiles of certificates.  This is the approach
started in [1].  If we adopt this blueprint, we will abandon [1].&lt;/p&gt;
&lt;p&gt;This is simpler, but seems a little arbitrary.  Using CMC is likely to be
supported by most CA’s because it is standards-based.  Also, there are likely
to be existing clients that already do CMC.&lt;/p&gt;
&lt;p&gt;The simpler mechanism is also limited, having no support for encryption or POP.
Ultimately, I think we would need to evolve to support something like CMC.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;We may need to add addtional data in the order_metadata, but this should not
result in database changes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;See above in proposed changes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h3&gt;Notifications &amp;amp; Audit Impact&lt;/h3&gt;
&lt;p&gt;None, other than additional audit changes needed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;There will need to be changes in either barbican-client or certmonger
to support the new API.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;There will be some additional processing that will need to be done to parse
the CMCRequest.  These changes are not covered in the spec.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Plugin developers will need to modify the supports() method to specify
which issuance methods they will support.  This information will be used
to appropriately route certificate requests, and to notify the client of
the CA’s capabilities when interacting with the interface defined in [3].&lt;/p&gt;
&lt;p&gt;Plugin developers will need to implement two new methods:
issue_simple_cmc_request() and issue_full_cmc_request() if they want to
support these requests.  We expect simple CMC to be easy to implement
because simple CMS == PKCS10.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;Assignee(s)&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;alee
chellygel
dave-mccowan
woodster&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Modify API code to parse the new Order parameters and pass the data
to lower levels.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add code to validate CMC request data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add code to certificate_manger.py to send the requests to the plugins.
Modify the plugin interface contract to provide default implementations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Plugins should modify the supports() method and implement the new methods
as appropriate.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add code to certificate_manager.py to parse a CMC Response and convert
into a ResultDTO object to return to barbican-core.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add client code.  This probably requires a separate blueprint.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;This work should do done in conjunction with the work on the interface
to get CA identifiers in [3].&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;More unit and functional tests will be needed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Docs (including sphinx and plugin docs) will need to be changed to
reflect this API.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;[1] &lt;a class="reference external" href="https://review.openstack.org/#/c/129695"&gt;https://review.openstack.org/#/c/129695&lt;/a&gt; Existing Blueprint to define a
set of common cert API parameters.&lt;/p&gt;
&lt;p&gt;[2] &lt;a class="reference external" href="http://tools.ietf.org/html/rfc5272"&gt;http://tools.ietf.org/html/rfc5272&lt;/a&gt; Certificate Management over CMS&lt;/p&gt;
&lt;p&gt;[3] API for getting CA identifiers is defined in this blueprint.  In addition,
there is an API for getting the CA signing certificate and intermediates.
&lt;a class="reference external" href="https://review.openstack.org/129048"&gt;https://review.openstack.org/129048&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[4] &lt;a class="reference external" href="https://tools.ietf.org/html/rfc7030"&gt;https://tools.ietf.org/html/rfc7030&lt;/a&gt; Enrollment over Secure Transport&lt;/p&gt;
&lt;p&gt;[5] &lt;a class="reference external" href="http://tools.ietf.org/html/rfc1485"&gt;http://tools.ietf.org/html/rfc1485&lt;/a&gt;
A string representation of distinguished names&lt;/p&gt;
&lt;p&gt;[6] &lt;a class="reference external" href="http://tools.ietf.org/html/rfc5280"&gt;http://tools.ietf.org/html/rfc5280&lt;/a&gt; Internet X.509 Public Key
Infrastructure Certificate and Certificate Revocation List (CRL) Profile&lt;/p&gt;
&lt;p&gt;[7] &lt;a class="reference external" href="https://review.openstack.org/129377"&gt;https://review.openstack.org/129377&lt;/a&gt; API for getting CA specific
certificate enrollment parameters.&lt;/p&gt;
&lt;p&gt;[8] LibEST implementation &lt;a class="reference external" href="https://github.com/cisco/libest"&gt;https://github.com/cisco/libest&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 18 Nov 2014 00:00:00 </pubDate></item><item><title>Expose CA enrollment templates</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/liberty/expose-ca-enrollment-templates.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/expose-ca-enrollment-templates"&gt;https://blueprints.launchpad.net/barbican/+spec/expose-ca-enrollment-templates&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Barbican will allow interaction with multiple Certificate Authorities through
multiple CA plugins.  Each plugin expects the certificate requests to conform
to a specific format and to have specific input parameters.  A common CA
interface will make it easier for clients to construct certificate requests.
Nonetheless, a mechanism is needed to expose the parameters required to make
a certificate request.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;A new resource has been proposed for certificate authorities in [1].  This
interface can be used to expose the parameters needed to create a certificate
request.  The details on the interface changes are shown in the REST API
section below.&lt;/p&gt;
&lt;p&gt;The data would be obtained from the plugins by implementing two new API calls:
get_enrollment_templates() and get_enrollment_template(template).  These calls
can have default implementations that return None so that not all plugins need
implement these calls immediately.&lt;/p&gt;
&lt;p&gt;For the common API, the methods get_common_enrollment_templates() and
get_common_enrollment_template() will be implemented to return the correct data.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Leave the code-base as it is.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;The following REST API operations will be added:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;GET /cas/templates/enrollment  – returns the request template for the
common CA API.  This will end up returning the data from
get_common_enrollment_templates().&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GET /cas/{ca_id}/templates/enrollment – returns the list of request
templates for a specific CA (as defined by ca_id).  This will end up returning
the data from calling get_enrollment_templates(plugin_ca_id) on the
specific plugin.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The ca_id values are defined in the spec for identifying ca_ids [1], which has
already been implemented in the server.&lt;/p&gt;
&lt;p&gt;This approach also leaves open the possibility to exposing other types of
templates in future as needed (like renewal and revocation templates).&lt;/p&gt;
&lt;p&gt;The data returned can consist of parameters and/or links for additional data.
All relevant links will be subordinate to the request template URL.&lt;/p&gt;
&lt;p&gt;For example, for the Dogtag CA, the call:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;GET /cas/{ca_id}/templates/enrollment could return:&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;{“templates”:[&lt;/dt&gt;&lt;dd&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;{“id”: “caUserCert”,&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;“name”: “Manual User Dual-Use Certificate Enrollment”,
“description”: “This certificate profile is for enrolling user certificates.”,
“link”: “&lt;a class="reference external" href="https://host:port/cas/ca1/templates/enrollment/caUserCert"&gt;https://host:port/cas/ca1/templates/enrollment/caUserCert&lt;/a&gt;”},&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;{“id”: “caServerCert”,&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;“name”: “Server Certificate Enrollment”,
“description”: “This certificate profile is for enrolling server certificates.”,
“link”: “&lt;a class="reference external" href="https://host:port/cas/ca1/templates/enrollment/caServerCert"&gt;https://host:port/cas/ca1/templates/enrollment/caServerCert&lt;/a&gt;”}&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;]}&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GET /cas/{ca_id}/templates/enrollment/caServerCert could return:&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;{“parameters”:[&lt;/dt&gt;&lt;dd&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;{“id”: “profile_id”,&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;“description”: “Profile ID”,
“syntax”: “string”},&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;{“id”: “cert_request_type”,&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;“description”: “Certificate Request Type”,
“syntax”: “cert_request_type”},&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;{“id”: “cert_request”,&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;“description”: “Certificate Request”,
“syntax”: “cert_request”},&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;{“id”: “requestor_name”,&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;“description”: “Requestor Name”,
“syntax”: “string”},&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;{“id”: “requestor_email”,&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;“description”: “Requestor Email”,
“syntax”: “string”},&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;{“id”: “requestor_phone”,&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;“description”: “Requestor Phone”,
“syntax”: “string”}&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;]}&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The idea would be that a client that filled in all the parameters listed above
would create a certificate request with all the required parameters.&lt;/p&gt;
&lt;p&gt;An example request using the above parameters would look like:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'certificate'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'meta'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s1"&gt;'profile_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'caServerCert'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'ca_id'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{ca_id}&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;
            &lt;span class="s1"&gt;'cert_request_type'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'pkcs10'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'cert_request'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&amp;lt;put PEM formatted CSR here&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'requestor_name'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'John Wood'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'requestor_email'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'jwood@rackspace.com'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'requestor_phone'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'555-1212'&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note that specification of ‘profile_id’ requires the specification of the ‘ca_id’.
This check is already enforced in the server.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None.  The data that are exposed through this interface are parameters which
the CA chooses to expose to show users how to interact with it. These are the
things that would be exposed by the CA on a web UI , say, or as part of
the CA’s client API.  This  data is necessarily public - otherwise no one would
know how to interact with the CA.&lt;/p&gt;
&lt;p&gt;All this info is queried by the CA plugin to the CA.  Barbican only reveals
what the CA chooses to expose.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h3&gt;Notifications &amp;amp; Audit Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;The python-barbicanclient will need to be enhanced to take advantage of this
new feature.  In particular, it may be possible to recurse through the parameters
either interactively or otherwise to generate valid cert requests.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Plugin developers may choose to implement the new methods to take advantage
of the new functionality.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;Assignee(s)&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;alee-3&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add code to implement the new API calls and call get_enrollment_templates() etc.
Add these calls and their default implementation to the plugin interface.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add code for get_common_enrollment_templates() and get_common_enrollment_template(x).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement get_enrollment_templates() and get_enrollment)template() for each plugin,
as needed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Document all, including sphinx documentation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;The current unit and functional tests will also be modified to reflect this
change.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;New feature that will need to be documented.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;[1] Spec for identifying CAs: &lt;a class="reference external" href="https://review.openstack.org/#/c/129048"&gt;https://review.openstack.org/#/c/129048&lt;/a&gt;&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;This spec was implemented in the server in Kilo.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
</description><pubDate>Fri, 17 Oct 2014 00:00:00 </pubDate></item><item><title>Identify available CAs</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/kilo/identify-cas.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/identify-cas"&gt;https://blueprints.launchpad.net/barbican/+spec/identify-cas&lt;/a&gt;&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;It is possible to have multiple CA plugins, each potentially talking to
multiple backend CA servers.  A mechanism is therefore needed to allow
the client to select a backend CA server.&lt;/p&gt;
&lt;p&gt;In addition, Dogtag plans to implement the ability to configure lightweight
sub CA’s - subordinate CA’s that can exist within the same CA instance.  This
opens up the possibility of configuring a separate CA instance for each
project, so that the project could have certificates that are scoped to the
project only.  Thus, a mechanism is also required to associate a project with
a preferred CA, so that if a client does not request a specific CA, the
preferred CA is selected.&lt;/p&gt;
&lt;p&gt;Also, a mechanism should be added to allow clients to discover the CA servers
available for a particular Barbican instance.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;We need to add a new resource CertificateAuthorities that will specify the CAs
that are available to Barbican.  This resource will permit listing CAs and
associating projects with a CA.  See the REST API section for details.&lt;/p&gt;
&lt;p&gt;Four new tables will be required:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;CertificateAuthority, which will list the CA’s available.  This table will
include the Barbican generated ca_id, the plugin name, plugin_ca_id,
information about the CA and a cache expiration time.  The data will be
assumed to be stale and to require a refresh when the cache expiration time
expires.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CertificateAuthorityMetadatum, which contains data about the CAs, to
be provided to the client.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ProjectCertificateAuthority, which will list the set of CA’s defined per
project.  If a project chooses to do so, it can specify a set of CA’s
(referenced by ca_ids) that a particular project can use.  The first entry
for a project will automatically be added to the PrefCA table for that
project to ensure that there will always be a preferred CA for a project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PreferredCertificateAuthority (PrefCA), which contains the preferred
CA entry for each project.  This table requires the project_id to be unique
so that there is only one preferred CA per project.  A special entry for
the preferred global CA will have “project_id” = 0.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;See the Data model section for details.&lt;/p&gt;
&lt;p&gt;The ProjectCertificateAuthority table will be updated through REST API calls
by a project administrator.&lt;/p&gt;
&lt;p&gt;The CertificateAuthority table will be updated as follows:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;On startup, Barbican should iterate through all the CA plugins and execute
certificate_resources.update_ca_list(plugin_name).  This will trigger a call
to a provides() method for each plugin.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The provides() call will query the backend-CA to determine which CAs are
provided.  It will return the relevant data ie. a list/dict of
(plugin_ca_id, description, ca_ski etc.) as needed to populate/update the
CertificateAuthority and CertificateAuthorityMetadatum table.
It will also return an expiration time for the data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The CA and CA metadata table would then be updated by a method defined in
Barbican core.  (eg. certificate_resources.update_ca_list(plugin_name)).
Barbican core will use the plugin_ca_id to map the CA entry to the correct
ca_id.  At this point: new CA’s will be added; decommisioned CA’s will be
removed; and existing CA’s will be updated.  In each case, the expiration
time will be updated.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A method is provided below for the user to obtain a list of available CA’s.
If the expiration time for a CA has elapsed, the plugin for that particular
CA will be queried by calling the provides() method.  The CA table and CA
metadata tables will be updated accordingly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If a certificate request is made and a ca_id is specified, the relevant
plugin will be looked up in the CA table.  If the entry for this ca_id is
stale, then the provides() method will be invoked for this CA to update
the CA table.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Logic when a certificate is requested:&lt;/p&gt;
&lt;p&gt;When a certificate is requested,&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;If a ca_id is provided:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If the ca_id is not defined in the CA table, a 400 error is returned.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If any entries for the project exists in the PCA table, and the ca_id is
not one of those entries, a 403 error is returned.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Otherwise the request is passed through to the plugin specified by the
entry in the CA table.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If a ca_id is not provided:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If at least one entry for the project exists in the PrefCA table, then
barbican core will select the preferred CA, and pass the request
through to that CA.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If no entry exists in the PrefCA table for the project, then the
global preferred CA specified in the prefCA table will be selected.
If no preferred CAs are defined, then the first CA plugin will be
selected.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;The plugin_ca_id will be passed to the plugin as part of the order_metadata.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;Four new tables will be added: CertificateAuthority (CA table),
CertificateAuthorityMetadatum (CAM table), ProjectCertificateAuthority
(PCA table) and PreferredCertificateAuthority (PrefCA table).&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;The CA table will have the following fields:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;ca_id - unique identifier for the CA generated by Barbican&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;plugin_name&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;plugin_ca_id - (string) identifier for the CA generated by the plugin
This identifier must be unique for the plugin.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;expiration_time&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ca_metadata (see below)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;To store metadata about each CA, data will be stored in a
CertificateAuthorityMetadatum (CAM) table.  This table will consist
of the following fields:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;ca_id - foreign key to CA table&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;key&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;value&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;The following key-value data will be stored to begin with:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;name - human readable name&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;description&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ca signing certificate&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;intermediates&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;A note about ids:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;The ca_id that will be presented to the client will be
the Barbican generated ca_id.  However, because the CAs that are
available are determined by the back-end CA, the plugin needs to provide
a plugin_ca_id that is unique to the plugin, so that the plugin_ca_id can
be mapped to the Barbican generated ca_id.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;The PCA table lists the CA’s defined for each project.  There can be
multiple entries for each project.  It will have the following fields:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;project_id&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ca_id (foreign key to the CA table)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;The PrefCA table lists the preferred CA either globally or for any particular
project.  This is to enforce the requirement that only one CA can be defined
to be preferred either globally or pre-project.  This table will have the
following fields:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;project_id – required to be unique&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ca_id – foreign key to CA table&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;We need a new resource to expose the CA’s available.  This resource will
allow the following operations:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;GET /cas - List all the available CAs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GET /cas/{ca_id} - Get details about CA referenced by ca_id.  This would
include things like a HATEOAS link to the CA information, name
and description.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GET /cas/{ca_id}/cacert - Get the base 64 encoded signing certificate for the
CA in PKCS7 format&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GET /cas/{ca_id}/intermediates - Get the CA cert and intermediates certs in
base 64 encoded PKCS7 format.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GET /cas/{ca_id}/projects - List projects which use the CA with the specified
ca_id.  Restricted to global admins.  This is an operation that will allow
global admins to clean up the PCA table, in case a CA is decommisioned.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;POST /cas/{ca_id}/add-to-project -  Add entry in PCA table for ca_id.  The
project_id is determined from authz.  Restricted to project admins.
If this is the first CA to be added to a project, it will be set as
preferred by adding an entry for that project in the PrefCA table.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;POST /cas/{ca_id}/remove-from-project -  Remove entry in PCA table for
ca_id.  The project_id is determined from authz.  Restricted to project
admins.  If the CA is the preferred CA for the project and no other CAs
exist in the PCA table, then the PrefCA entry will be removed too.  If
other entries exist in the PCA table, then a 400 error is returned.
(“Cannot remove a preferred CA. Select another project CA to be preferred
first.”)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;POST /cas/{ca_id}/set-preferred -  Set ca_id to be a preferred CA for the
project.  A 400 error should be returned if a PCA entry does not already
exist for this project_id/ca_id. Restricted to project admins.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;POST /cas/{ca_id}/set-global-preferred -  Set ca_id as a global preferred
CA.  This CA is invoked if no ca_id is specified in a request, and no PCA
entries exist for the project.  Restricted to global admins.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;POST /cas/{ca_id}/unset-global-preferred -  Unset ca_id as a global
preferred CA.  Restricted to global admins.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Also, an optional metadata parameter (ca_id) will be provided in the Order
for a Certificate, and will be processed as described above.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h3&gt;Notifications &amp;amp; Audit Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;python-barbicanclient will need new methods to check the list of CAs and
to invoke a specific ca_id if requested.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;This feature requires database access to get the CA/project/plugin information
on each certificate order request, which will have an impact on both the API
and worker nodes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Migration scripts will need to be run on already existing deployments to add
the new tables.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Plugin developers should write a provides() method that returns the correct
information.  We can provide a default implementation that creates a CA table
entry based on the plugin_name.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;Assignee(s)&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;alee-3
dave-mccowan&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add new data models (PCA, PrefCA, CA, CAM tables)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add default provides() call to the back-end plugin contract.  Add the logic
that populates the CA table on startup.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add /cas and the relevant REST API calls to retrieve/set these resources.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add CA selection logic to the certificate request flow.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add each plugin specific provides() method.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;The current unit and functional tests will also be modified to reflect these
changes.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;This is a new feature that will need to be documented.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 16 Oct 2014 00:00:00 </pubDate></item><item><title>Storing metadata to allow the use of per-secret policy</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/kilo/add-per-secret-policy.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/add-per-secret-policy"&gt;https://blueprints.launchpad.net/barbican/+spec/add-per-secret-policy&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is a proposal to add per-secret specific policy in Barbican to augment
the generic operation based policy in policy.json. The idea is to store
attributes that help determine whether or not a secret or container could
be accessed (like an include_list of users) per secret.&lt;/p&gt;
&lt;p&gt;Oslo policy allows you to access those attributes and pass them to the RBAC
rules engine as a dictionary of target.* attributes, and used in policy
enforcement.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Most recently, Neutron LBaaS tried to figure out how to grant the LBaaS system
user the ability to retrieve secrets (cert containers and secrets) in order to
create load balancer configuration.  The solution that was decided upon was
trusts.  That is, a trust was created on the keystone server for the LBaaS
user for the relevant project ID.&lt;/p&gt;
&lt;p&gt;While this mechanism will work, a trust is pretty heavy-handed.  Essentially,
it gives permission to the LBaaS user to impersonate the user for the
relevant project, as long as the trust is valid (which could easily
be forever).  If the LBaaS user were ever hijacked, they would not only be
able to access all the Barbican data, but they would be able to interact
with all the other services as that user.&lt;/p&gt;
&lt;p&gt;Indeed, as more projects integrate with Barbican, the requirement for
service users to obtain barbican secrets will come up again and again.
Proliferating trusts throughout the services simply to do something as basic
as retrieving secrets seems like a recipe for disaster.&lt;/p&gt;
&lt;p&gt;In addition, recently there have been requests to be able to specify that
some secrets were private.  That is, only the secret creator (the user that
created the secrets) should be able to extract them.  Now, one might argue
that one could create a project for each user - but that seems like a very
burdensome solution.&lt;/p&gt;
&lt;p&gt;Both of these problems (and perhaps others) can be solved by using per-secret
access attributes to further refine the policy associated with a secret.  In
policy parlance, this is using attributes of the target (resource being
accessed, in this case, a secret or a container) to further refine policy.&lt;/p&gt;
&lt;p&gt;This is something that is done, for instance, in Keystone.  See the rules in
&lt;a class="reference external" href="https://github.com/openstack/keystone/blob/master/etc/policy.v3cloudsample.json"&gt;https://github.com/openstack/keystone/blob/master/etc/policy.v3cloudsample.json&lt;/a&gt;
which refer to target.  These values are populated in
keystone/common/controller.py (in the definition of protected()).&lt;/p&gt;
&lt;p&gt;To make things clearer, I will separate the solution for this second problem
(“private secrets”) into a separate follow-on spec.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The spec deals only with the problem posed by LBaaS.  That problem is: how do we
allow access to a secret by a user that is not part of the secret’s project.&lt;/p&gt;
&lt;p&gt;The proposal is to store access control data with each secret or container that
could be used to augment the existing policy for retrieval on a per-resource basis.&lt;/p&gt;
&lt;p&gt;This feature can be broken down in terms of four subproblems:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;What operations will the proposed ACLs cover, and what will be the default
policy for each operation?  See the Operations section below.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What does the client send into the server when setting the ACLs for a secret
or container?  See REST API section below.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How is this ACL information stored within the database?  See the Database
section below.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How is this data extracted and presented to the Oslo layer to do RBAC enforcement?
See the Policy section below.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;section id="operations"&gt;
&lt;h3&gt;Operations&lt;/h3&gt;
&lt;p&gt;The ACL permissions here correspond to actions that some user outside of the
creator’s project can perform on a secret or container.  These actions include:&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;get:  For secrets, someone with ‘get’ permission will be able to retrieve&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;secret metadata and payload.  For containers, they will be able to
retrieve the container (which is essentially all metadata).  Accessing
secrets referenced within the container will require ‘get’ permission
on each secret.  For ‘Kilo’, get permission on the container will not
automatically cacade down to the secret.  This is the only action to be
implemented for K.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;delete: Ability to delete a secret or container.  Currently, this permission&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;is restricted to a particular role (“creator”?) in the secret’s project.
For Kilo, this will not change.  In particular, its not clear that we would
ever want someone outside the project to be able to delete a secret or
container.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;write: Ability to modify a project/container.  Currently typed containers and&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;secrets are immutable.  Even if they were not, its not clear someone from
a different project should be able to modify a secret/container.  This
will not be implemented for K.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;change-acl: Ability to change the ACL for a secret.  For K, this will be&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;restricted to the secret/container’s creator (ie. the user that created the
secret/container).&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A new parameter (“acl”) will be added to POST for secrets and containers.
The data in this field has the following format:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"get"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"users"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"some_user_id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="s2"&gt;"another_user_id"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
           &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The data in those fields will be placed directly into the ContainerACL and
SecretACL tables below.&lt;/p&gt;
&lt;p&gt;There has been some discussion of adding parameters for whitelisted groups
and projects to the acl.  This requires additional discussion because groups
are not specified in the keystone token, and roles should also be defined
within projects.  As there is no current need for these parameters, we will
defer adding them till L+.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In addition, a new endpoint will be provided to allow a user to change the
ACL on a secret or container:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="o"&gt;/&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;UUID&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;/&lt;/span&gt;&lt;span class="n"&gt;acl&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;where the body would be an ACL in the same format as above.  This endpoint
would be limited to uid == &amp;lt;uid of creator&amp;gt; by default.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ACL data will not be returned by default with a GET request.  Rather, a new
route will be provided to retrieve the ACL:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;GET /secrets/&amp;lt;secret_uuid&amp;gt;/acl&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;which would return the ACL as shown above.  This endpoint would be limited to
uid: &amp;lt;creator&amp;gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When orders are created, the Barbican server will need to keep track of the
order’s creator to ensure that the order’s creator has permissions to access
the secrets.&lt;/p&gt;
&lt;p&gt;For example, when generating a certificate using the stored key mechanism, the
asynchronous worker will need to access a container and the private key
referenced within that container.  This should only be allowed if the order’s
creator has access to the relevant resources.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;For secrets and containers, we will need add a column to store the creator
of the secret.  This would be populated by the creator’s user_id.  It may
also be useful to store the creator’s project_id, given that we plan to
remove the secret/project table.&lt;/p&gt;
&lt;p&gt;We will also need to add column to store the creator of an Order, so that any
secrets/containers that are generated when an Order is processed will be
stamped with their creator.&lt;/p&gt;
&lt;p&gt;We also need to create two new tables: ContainerACL and SecretACL, in which
to store ACL data.  The fields for the SecretACL table will be as follows:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;secret_id: foreign key to Secrets table
action: currently, only “read” will be implemented
users: string, list of whitelisted users for specified action&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;In L+, we may decide to add columns to allow for whitelisted groups or projects.
For now, only users are whitelisted.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="policy"&gt;
&lt;h3&gt;Policy&lt;/h3&gt;
&lt;p&gt;When a container or secret is accessed, the ACL data is retrieved from the
database and provided to the RBAC layer as target.* attributes.  For getting
a secret, for example, we could pass in target.user_whitelist.&lt;/p&gt;
&lt;p&gt;The policy rule would then look something like:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;can_read_shared&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;user_in_user_whitelist&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;OR&lt;/span&gt; &lt;span class="n"&gt;current_resource_permissions&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The current_resource_permissions part is basically that the user has the relevant
role in the secret creator’s project.&lt;/p&gt;
&lt;p&gt;We may need to extend (and upstream) oslo-policy to allow lists to be processed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;We could use trusts, but they are, as we described before, very heavy handed.
All in all, this is something that is simply required in Barbican.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;This improves security in the stack as a whole by eliminating the
requirement for a trust, and rather, providing granular per-secret
permissions.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h3&gt;Notifications &amp;amp; Audit Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;python-barbicanclient will need to be updated to provide an interface to
populate the extra parameters.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Accessing a secret/container will require two database calls: one to get
secret/container include)list as part of the RBAC engine’s rules
enforcement, and one to actually get the secret/container.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Neutron and other service users that will be accessing secrets in Barbican
will be able to do so using the new mechanism, rather than a trust.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Changes will likely need to be made in the neutron code to take advantage of
this mechanism.  The current mechanism of using trusts should still work.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;Assignee(s)&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;alee
rm_work&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Add new fields to the database tables, and new parameters to the REST API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add logic to stamp secrets/containers created through the REST API or through
Orders with their creator.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add logic to retrieve ACL data from the database and provide to RBAC layer as
target.* attributes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify policy rules based on these target.* attributes.  It may be necessary to
extend oslo policy here to process lists correctly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify neutron code/barbican client to take advantage of this new mechanism.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;The current unit tests will also be modified to have this change reflected upon
them.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Neutron and Barbican docs will need to be changed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Diagram showing Neutron LBaaS detailed flow. &lt;a class="reference external" href="http://goo.gl/Wc8oIj"&gt;http://goo.gl/Wc8oIj&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Earlier blueprint with similar ideas.
&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/secret-isolation-at-user-level"&gt;https://blueprints.launchpad.net/barbican/+spec/secret-isolation-at-user-level&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 09 Oct 2014 00:00:00 </pubDate></item><item><title>Change GET decrypted secrets to unique URI</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/kilo/api-change-get-secrets-decrypted.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/api-change-get-secrets-decrypted"&gt;https://blueprints.launchpad.net/barbican/+spec/api-change-get-secrets-decrypted&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Currently retrieving the metadata and actual decrypted data for a secret stored
in Barbican uses the same URI, with only the Accept header used to determine
which response to return. This complicates deployments with RBAC systems in
front of Barbican (such as Repose - &lt;a class="reference external" href="http://openrepose.org/"&gt;http://openrepose.org/&lt;/a&gt;) or as middleware
(such as EOM - &lt;a class="reference external" href="https://github.com/racker/eom"&gt;https://github.com/racker/eom&lt;/a&gt;). It also requires adding logic
like this to the Barbican app when it is used to enforce RBAC:
&lt;a class="reference external" href="https://github.com/openstack/barbican/blob/master/barbican/api/controllers/__init__.py#L53"&gt;https://github.com/openstack/barbican/blob/master/barbican/api/controllers/__init__.py#L53&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This blueprint proposes using a unique URI to access decrypted secrets, such as
this: &amp;lt;host&amp;gt;/v1/secrets/&amp;lt;secret-UUID&amp;gt;/payload&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Currently to retrieve a secret’s metadata and its decrypted data, the same URI
is used, such as this:&lt;/p&gt;
&lt;p&gt;GET &amp;lt;host&amp;gt;/v1/secrets/&amp;lt;secret-UUID&amp;gt;&lt;/p&gt;
&lt;p&gt;It would be easier to configure RBAC systems that operate in front of a
Barbican deployment if these two retrieval types were distinguished by URI.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;This blueprint calls for adding a new URI structure to retrieve decrypted
secrets as follows:&lt;/p&gt;
&lt;p&gt;GET &amp;lt;host&amp;gt;/v1/secrets/&amp;lt;secret-UUID&amp;gt;/payload&lt;/p&gt;
&lt;p&gt;So this would include adding a new Pecan sub-controller to handle the ‘payload’
requests, adding unit and functional tests for the new ‘payload’ resource, and
updating API documentation.&lt;/p&gt;
&lt;p&gt;The existing Accept-based decryption approach would &lt;em&gt;not&lt;/em&gt; be removed in the
current ‘v1’ API version to avoid breaking the current API contract, but could
be removed in the next version (‘v2’) of the API (not part of this blueprint).&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Another option is to use a URI such as this to retrieve decrypted secrets:&lt;/p&gt;
&lt;p&gt;GET &amp;lt;host&amp;gt;/v1/secrets/&amp;lt;secret-UUID&amp;gt;.payload&lt;/p&gt;
&lt;p&gt;This approach would require parsing within the Pecan controller logic however.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;This blueprint would add a new URI to retrieve decrypted secrets:&lt;/p&gt;
&lt;p&gt;GET &amp;lt;host&amp;gt;/v1/secrets/&amp;lt;secret-UUID&amp;gt;/payload&lt;/p&gt;
&lt;p&gt;The Accept header would still be used as now to specify the desired format to
return decrypted secrets in, but the ‘application/json’ format would no longer
be needed/used.&lt;/p&gt;
&lt;p&gt;The current URI to retrieve secrets would still function as it does now, but
the decryption options could be removed in the next API version (‘v2’) by a
future blueprint.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None, as the same policy rule (‘secret:decrypt’) for the new decrypt action
will be used as for the current header-based decryption mechanism.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h3&gt;Notifications &amp;amp; Audit Impact&lt;/h3&gt;
&lt;p&gt;None, though auditing might actually be easier due to the unique-URI per action
approach taken by this blueprint.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;The Python Barbican client will also need to be updated to work with this
change.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;The proposed change would clean up the Pecan controllers code a bit,
segregating secret metadata and decrypted payload concerns from each other.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;jaosorior&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;john-wood-w&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Add new ‘payload’ sub-resource controller off the ‘secrets’ resource, using the ‘secret:decrypt’ policy action&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add associated unit and functional tests per below&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update API documentation per below (currently located here: &lt;a class="reference external" href="https://github.com/cloudkeep/barbican/wiki/Application-Programming-Interface"&gt;https://github.com/cloudkeep/barbican/wiki/Application-Programming-Interface&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update the Python Barbican Client to utilize this new resource. If it is not available (due to older Barbican deployments), it should fail over to using the current decrypt mode&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Add unit and functional tests to test decrypted secret retrievals using the new
‘payload’ resource off of the ‘secrets’ resource. These new tests should
function properly in the Devstack gate job.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;API documentation will need to be updated to reflect these new secret
decryption API call, and to mark as ‘deprecated’ the current Accept header
based approach.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 02 Oct 2014 00:00:00 </pubDate></item><item><title>Replace the concept of tenants in the code-base in favor of projects</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/kilo/replace-concept-of-tenants-for-projects.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/replace-concept-of-tenants-for-projects"&gt;https://blueprints.launchpad.net/barbican/+spec/replace-concept-of-tenants-for-projects&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To enforce a uniform and consistent code-base, it is also necessary to make use
of concepts in a consistent way. As a notorious example of this, the incidental
usage of the concepts ‘tenant’ and ‘project’ throughout the code-base. The
proposition provided in this blueprint is to finally replace one concept for
the other, and thus end this lack of uniformity.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Even though, it has been talked of following the steps taken by the Keystone
team of starting to enforce the usage of the concept of ‘projects’ instead of
tenants; there are still 580 occurrences of the word ‘tenant’ in the Barbican
code-base alone (At the time that this blueprint was written), as opposed to
the 103 occurrences of the word ‘project’. This shows lack of uniformity, which
degrades the consistency throughout the code-base.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Thus, to address the aforementioned issue, I propose to replace every instance
of ‘tenants’ from the code-base, and enforce the usage of ‘projects’. This is
to, not only have a consistent code-base, but also have consistency towards
other projects such as Keystone.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Leave the code-base as it is.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;There will be impacts in the data model, since the concept of ‘tenants’ is
actually being used there. Thus, the Tenant and the TenantSecret classes will
be replaced with a Project and ProjectSecret classes respectively. On the other
hand, tables containing columns with the word ‘tenant’ will also need to be
replaced, and with those, migration scripts will need to be added
(the TenantSecret, Tenant, EncryptedDatum, KEKDatum, Order and Container
classes/tables will be affected).&lt;/p&gt;
&lt;p&gt;On the other hand, keystone_id will also be replaced from the Tenant (which
will be called Project) in favor of calling it ‘project_id’, since this was
initially named due to the confusion as to whether it should be ‘tenant_id’ or
‘project_id’. The proper business logic around this which involves changing how
the context is filled, and how it is passed to the controllers will also
reflect this change. So, in summary, ‘keystone_id’ will also be replaced by
‘project_id’&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h3&gt;Notifications &amp;amp; Audit Impact&lt;/h3&gt;
&lt;p&gt;If the word ‘tenant’ is being used while emitting notifications, this will be
changed to ‘project’. Other than that, there will not be any extra impact.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;There are certain arguments taken by the python-barbicanclient that will change
due to this.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Migration scripts will need to be run on already existing deployments. There
will be no other impact otherwise.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Developers hopefully will stop using the term ‘tenant’ in barbican.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;Assignee(s)&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;juan-osorio-robles&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Replace all trivial instances in the code-base&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Replace instances in the data model (write the proper migration scripts)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Replace all instances in the python-barbicanclient&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;The current unit tests will also be modified to have this change reflected upon
them.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;If there exist instances of the term in the wiki, these should be changed also.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Tue, 30 Sep 2014 00:00:00 </pubDate></item><item><title>Creation of a Babrican Plugin to use HP Atalla ESKM.</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/juno/hp-eskm-plugin.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/hp-eskm-plugin"&gt;https://blueprints.launchpad.net/barbican/+spec/hp-eskm-plugin&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This effort will enhance Barbican by adding a crypto plugin to allow use of
Atalla ESKM from HP. Atalla ESKM is a HSM appliance for generating and managing
cryptographic keys. By adding an optional plugin to Barbican, users have the
option of integrating OpenStack with existing or new Atalla ESKM installations.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Deployers of an OpenStack cloud may have, or wish to have an Atalla ESKM
Appliance for key management. In this case, it is desirable to utilise the
appliance alongside the new OpenStack installation for enhanced security.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The proposed changes to Barbican are, creation of an optional plugin to talk
to an ESKM appliance. This plugin will be based of off the CryptoPlugin base
and encapsulate all necessary functionality. The plugin will communicate over
a secure network link to a remote appliance using a vendor specific protocol.&lt;/p&gt;
&lt;p&gt;No changes to the core of Barbican are required.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;Alternatively, Atalla ESKM supports the KMIP industry standard protocol for key
exchange. KMIP is something planned for Barbican in the future but at the time
of writing has not yet been implemented.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;This change touches sensitive data (tokens, keys, and user data) since it will
pass key data through to an ESKM server and receive the results prior to
encryption. User data is protected using a key encryption key and 256 bit AES
CBC encryption. The key encryption key is never stored and is fetched on demand
from the ESKM appliance.&lt;/p&gt;
&lt;p&gt;This change utilises encryption algorithms from the ‘cryptography’ python
module but does not introduce any additional cryptographic dependencies into
Barbican.&lt;/p&gt;
&lt;p&gt;This change requires a network connection to be established between Barbican
and an ESKM appliance. This connection is protected using TLSv1 and client
identification certificates. Key material is transmitted over this connection.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h3&gt;Notifications &amp;amp; Audit Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;A performance impact is introduced by this change, communication over a network
link to a remote ESKM appliance may take time. This is multiplied by the need
to request a key encryption key from ESKM as part of all requests. This
performance impact is accepted in return for the improved security gained by
not caching the key encryption key locally.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;The following new config options are added, they are specific to the plugin and
need not be used otherwise. All options live within the ‘eskm_crypto_plugin’
group.&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Option&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Meaning&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;eskm_crypto_plugin.crt_file_path&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;ESKM client certificate file path.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;eskm_crypto_plugin.key_file_path&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;ESKM client key file.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;eskm_crypto_plugin.key_password&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;ESKM client key password.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;eskm_crypto_plugin.user_name&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;ESKM user name.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;eskm_crypto_plugin.user_pass&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;ESKM user password.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;eskm_crypto_plugin.eskm_host&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;ESKM host IPs, comma separated.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;eskm_crypto_plugin.eskm_port&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;ESKM port number.&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;tim-kelsey&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;None&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Create spec (this spec).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write the plugin and tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Confirm all Barbican tests, new and old, still pass.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Review the code.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;No compulsory dependencies are introduced, but an Atalla ESKM appliance must
be available if a deployer wishes to use this plugin.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;A suite of unit tests will be produced to test the new code.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Documentation may need updating to reflect the existence of the plugin and its
configuration options.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Fri, 15 Aug 2014 00:00:00 </pubDate></item><item><title>Add containers to python-barbicanclient</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/juno/client-add-containers.html</link><description>

&lt;p&gt;Launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/python-barbicanclient/+spec/client-add-containers"&gt;https://blueprints.launchpad.net/python-barbicanclient/+spec/client-add-containers&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The Secret Containers resource is now available in Barbican, so it should
also be added to the client.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;We need to be able to consume and create Container resources in the Python
library using Python objects to represent the containers.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;Add new Classes to the client to represent the different types of Containers
available in Barbican in a new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;containers&lt;/span&gt;&lt;/code&gt; module:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;barbicanclient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;containers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Container&lt;/span&gt;
&lt;span class="n"&gt;barbicanclient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;containers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CertificateContainer&lt;/span&gt;
&lt;span class="n"&gt;barbicanclient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;containers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RSAContainer&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The classes should be usable thusly:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;barbicanclient.containers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;RSAContainer&lt;/span&gt;

&lt;span class="c1"&gt;# New Generic Container&lt;/span&gt;
&lt;span class="n"&gt;my_container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;my_container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Secret Name in Container"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Secret&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;my_container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# New RSA Container&lt;/span&gt;
&lt;span class="n"&gt;my_rsa_container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RSAContainer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;my_rsa_container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;public_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Secret&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;my_rsa_container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;private_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Secret&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;my_rsa_container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;private_key_passphrase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Secret&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;#optional&lt;/span&gt;
&lt;span class="n"&gt;my_rsa_container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# RSAContainer should be subclassed from Container&lt;/span&gt;
&lt;span class="n"&gt;my_rsa_container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"public_key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Secret&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;# should work&lt;/span&gt;
&lt;span class="n"&gt;my_rsa_container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"unsupported_secret_name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Secret&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;# should raise exception&lt;/span&gt;

&lt;span class="c1"&gt;# New Certificate Container&lt;/span&gt;
&lt;span class="n"&gt;my_cert_container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CertificateContainer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;my_cert_container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;certificate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Secret&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;my_cert_container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;private_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Secret&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;my_cert_container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;private_key_passphrase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Secret&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;my_cert_container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;intermediates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Secret&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;my_cert_container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# CertificateContainer should be subclassed from Container&lt;/span&gt;
&lt;span class="n"&gt;my_cert_container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'certificate'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Secret&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;# should work&lt;/span&gt;
&lt;span class="n"&gt;my_cert_container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'unsupported_secret_name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Secret&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;# should raise exception&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Objects should be lazy, so requests should not be sent until the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;save()&lt;/span&gt;&lt;/code&gt;
method is called.  The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;save()&lt;/span&gt;&lt;/code&gt; method should also recursively store secrets
if they have not yet been stored to the Barbican instance.&lt;/p&gt;
&lt;p&gt;Once the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;save()&lt;/span&gt;&lt;/code&gt; method is called for the first time the Container becomes
immutable, subsequent calls to &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;add()&lt;/span&gt;&lt;/code&gt; or &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;save()&lt;/span&gt;&lt;/code&gt; should raise exceptions.
Basically, any action that would modify the container, except for &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;delete()&lt;/span&gt;&lt;/code&gt;,
should raise an exception.&lt;/p&gt;
&lt;p&gt;Retrieving existing containers should be done via a &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ContainerManager&lt;/span&gt;&lt;/code&gt; accessible
from the client object:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;barbicanclient&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;

&lt;span class="n"&gt;barbican&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;my_container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;barbican&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;containers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'https://ref_to_container/UUID'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;get()&lt;/span&gt;&lt;/code&gt; method should return an instance of the appropriate Container
class. Listing existing methods should be done via the &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;ContainerManager&lt;/span&gt;&lt;/code&gt;
as well:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;my_containers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;barbican&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;containers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;offset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;my_containers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# should return True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Container deletion should be done on either the Container object or using
the ContainerManger:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;my_container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;barbican&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;containers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'https://ref_to_container/UUID'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;my_container&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;# or&lt;/span&gt;
&lt;span class="n"&gt;barbican&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;containers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'https://ref_to_container/UUID'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;The proposed functionality above pushes most of the actions to the
Container objects, while keeping the ContainerManager functionality somewhat
light.  As an alternative, the ContanerManager could perform all of the
functionality, while making the Container objects simple.&lt;/p&gt;
&lt;p&gt;I think container creation in a single method could get ugly really fast,
so I would prefer to avoid it.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h3&gt;Notifications &amp;amp; Audit Impact&lt;/h3&gt;
&lt;p&gt;Logging should be done in a manner consistent with the rest of the library.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None as this is new functionality.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Blueprint Draft: dougmendizabal
Implementation: TBD&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Implement the new &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;containers&lt;/span&gt;&lt;/code&gt; module.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Testing should be consistent with existing testing in the library.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;All new Container functionality needs to be documented.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;Containers in the Client etherpad: &lt;a class="reference external" href="https://etherpad.openstack.org/p/python-barbicanclient-containers"&gt;https://etherpad.openstack.org/p/python-barbicanclient-containers&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Mon, 28 Jul 2014 00:00:00 </pubDate></item><item><title>Restructure PKCS11 Plugin</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/juno/restructure-pkcs11-plugin.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/restructure-pkcs11-plugin"&gt;https://blueprints.launchpad.net/barbican/+spec/restructure-pkcs11-plugin&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The current PKCS11 plugin assumes that it has sufficient storage to create
a KEK per project/tenant. This assumption is untrue for many HSMs so we
propose to introduce a master KEK stored in the HSM that wraps per project
KEKs to resolve the problem.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;The PKCS11 plugin creates a key encrypting key (KEK) per project/tenant.
When connecting to an HSM with limited storage, this system can exhaust
available space on the HSM and fail to create KEKs for new project/tenants.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;A master KEK wrapping a project KEK will resolve the storage problem by
keeping a minimum of keys in the actual HSM while still using a different
encryption key per project/tenant. The hierarchy would look like this:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="o"&gt;+--------------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;  &lt;span class="n"&gt;Master&lt;/span&gt; &lt;span class="n"&gt;KEK&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-----+--------+&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-----+-----+&lt;/span&gt;       &lt;span class="o"&gt;+-----------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Wrapped&lt;/span&gt; &lt;span class="n"&gt;KEK&lt;/span&gt;&lt;span class="o"&gt;+-------+&lt;/span&gt;&lt;span class="n"&gt;Encrypted&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+-----------+&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;Secret&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;
                    &lt;span class="o"&gt;+-----------&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The sequence diagram of the decryption process will look like this:&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;::&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;barbican                         DB                        HSM
+        Get master KEK handle   +                        +
| &amp;lt;—————————————————–&amp;gt; |
|  Get wrapped project KEK       |                        |
| &amp;lt;—————————-&amp;gt; |                        |
|       Unwrap project KEK (stays|in HSM)                 |
+——————————————————-&amp;gt; |
|          project KEK handle    |                        |
| &amp;lt;——————————————————-+
|    Get encrypted secret        |                        |
| &amp;lt;—————————-&amp;gt; |                        |
|          Decrypt secret using project KEK handle        |
| &amp;lt;—————————————————–&amp;gt; |&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;The data model may need to be expanded to support storing a per project KEK.
We propose that this be accomplished by creating a new table that stores the
wrapped KEK bytes with a foreign key to project/tenant.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;The risks of the PKCS11 plugin remain largely the same. While the KEKs are
no longer stored exclusively in the HSM, the KEK is always encrypted when
outside the HSM.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h3&gt;Notifications &amp;amp; Audit Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;There is an additional decryption round trip to the HSM. Previously
decrypting a secret required finding the project KEK and then sending
the encrypted bytes to the HSM for decryption. With the new system
we must find the master KEK, decrypt the wrapped project KEK, then
decrypt the user secret using that unwrapped KEK.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Paul Kehrer (reaperhulk)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Add new model to barbican&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update PKCS11 plugin to do wrap/unwrap and consume the new model.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;The unit tests for the PKCS11 plugin will change to reflect the new calls
made to the HSM and the data stored in the models.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Update the documentation to describe the manner of operation of the plugin.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/restructure-pkcs11-plugin"&gt;https://blueprints.launchpad.net/barbican/+spec/restructure-pkcs11-plugin&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 17 Jul 2014 00:00:00 </pubDate></item><item><title>Transport Key Wrapping</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/juno/add-wrapping-key-to-barbican-server.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/add-wrapping-key-to-barbican-server"&gt;https://blueprints.launchpad.net/barbican/+spec/add-wrapping-key-to-barbican-server&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Secrets are currently passed from Barbican clients to the Barbican server
encrypted only by TLS.  For Common Criteria environments, this is
insufficient.  Secrets need to be encrytped within the TLS stream at the point
of origin, and ideally only decrypted when the secret is stored.  In the case
where a hardware token is used, this would happen in the token, so that even if
an attacker were able to gain access to the Barbican server, and was able to
introspect the process memory, no secrets could be deciphered.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;See above.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Mechanism for Storing Keys using Key Wrapping:&lt;/strong&gt;&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Client elects to use key wrapping to store a secret, and therefore will use
a two step storage mechanism for its secret.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Client does a POST to /secrets without a payload.  Client also specifies
transport_key_needed=true in the request.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server notices that transport_key_needed=true and looks for a plugin
that supports storage with key wrapping.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The logic is something like this&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;plugin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;list_of_plugins&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;plugin&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_transport_key&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;transport_key_found&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;put&lt;/span&gt; &lt;span class="n"&gt;transport_key&lt;/span&gt; &lt;span class="n"&gt;URL&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;transport_key_ref&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;success&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;failure&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;No&lt;/span&gt; &lt;span class="n"&gt;plugin&lt;/span&gt; &lt;span class="n"&gt;available&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;ol class="arabic simple" start="4"&gt;
&lt;li&gt;&lt;p&gt;Note that plugin.get_transport_key() will be defined within the abstract
base secret_store class to return None.  This means that plugins that wish
to support key wrapping will need to override this method to return a
transport_key_id (a reference to the key in the transport key repo).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It is expected that the plugin will be responsible for populating the
TransportKeyRepo with the correct key.  This could occur, for example,
on module startup, or when the first call to get_transport_key() is made.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Client gets the transport key from the transport key resource.  To
improve performance, the client will probably cache this key.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Client uses transport key to do key wrapping as expected.
Specifically - wrap the secret with a session key, then wrap session
key with transport key, then place in ASN1 structure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Client returns encrypted blob and the transport key reference in the PUT
/secret/{id} request.  We can use the parameter transport_key_ref.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server notices that transport_key_ref has been set.  It looks up the plugin
associated with that transport key from the TransportKeyRepo.
If the plugin is not available or the transport key does not exist, throw
failure (400)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pass the parameter transport_key_id in the SecretDTO, and call
store_secret().&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Plugin detects that transport_key_id is set, and processes accordingly.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Mechanism for Retrieving Keys using Key Wrapping:&lt;/strong&gt;&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;Client elects to retrieve a secret using key wrapping.  It first retrieves
the metadata using a GET.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the plugin that stored the secret supports key_wrapping and a
transport key exists, return the URL for the transport key in
transport_key_ref.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The client fetches the transport key and caches it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Client generates a symmetric key (session key) and wraps it with the
transport key.  Client sends the trans_wrapped_session_key to the server
as part of the GET request for the secret.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The server writes this key (trans_wrapped_session_key) into the
secret_metadata and calls get_secret()&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Plugin detects that this parameter has been written and retrieves the
secret accordingly.  The storing server will extract the session key
and will encrypt the response with the session key.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;On returning the secret, the plugin will remove the
trans_wrapped_session_key from the secret_metadata.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Client will decrypt the response from the server using the session key.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;The above solution is the culmination of a series of design discussions
at the Atlanta summit.  An old design can be found here:
&lt;a class="reference external" href="http://pki.fedoraproject.org/wiki/Barbican_server_add_wrapping_key"&gt;http://pki.fedoraproject.org/wiki/Barbican_server_add_wrapping_key&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;This change requires a new resource to be made available through the REST
interface and stored in the database - transport keys.&lt;/p&gt;
&lt;p&gt;The code to implement this new resource/model has already been merged.
&lt;a class="reference external" href="https://review.openstack.org/94875"&gt;https://review.openstack.org/94875&lt;/a&gt; - Add transport key as a resource.&lt;/p&gt;
&lt;p&gt;These are new objects.  They will be populated by any plugins that support
key wrapping whenever the get_transport_key() method is invoked.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;The following API methods will be changed:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;POST /secrets&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A new optional parameter will be added “transport_key_needed” which will
have the possible values of “true|false”.  The parameter defaults to
“false”.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This parameter will have an effect when the two step storage mechanism is
used.  In this case, when there is no payload, if transport_key_needed
is set to true, then a suitable plugin will be found and a transport key
URL will be returned in the response in the field “transport_key_ref”.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Return Error 400 if a suitable plugin/transport key cannot be found when
transport_key_needed=true.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;POST /secrets (with a payload)&lt;/dt&gt;&lt;dd&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A new optional parameter will be added: “transport_key_ref”.  This will
contain the URL for the transport key used to encode the secret.  Use
of this parameter will imply that the secret has been wrapped.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Return error 400 if the suitable plugin/transport key cannot be found.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;PUT /secrets/foo&lt;/dt&gt;&lt;dd&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A new optional parameter will be added: “transport_key_ref”.  This will
contain the URL for the transport key used to encode the secret.  Use
of this parameter will imply that the secret has been wrapped.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Return error 400 if the suitable plugin/transport key cannot be found.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;GET /secrets/foo (metadata only)&lt;/dt&gt;&lt;dd&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If the secret is stored by a plugin that supports key_wrapping, then
the a new parameter “transport_key_ref” will be added to the metadata
response.  This will contain a reference to the transport key for that
plugin.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;GET /secrets/foo (the actual secret)&lt;/dt&gt;&lt;dd&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A new optional query parameter trans_wrapped_session_key
will be added to this method.  This parameter will contain a session
key wrapped by a transport key to be used for retrieving the secret.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;GET/DEL/POST /transport-keys&lt;/dt&gt;&lt;dd&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;This is mentioned here for completeness.  The methods for these resources
have already been merged into the code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GET will be used by clients to retrieve a transport key.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;POST/DEL can be used by plugin administrators to add or remove transport
keys.  These operations will not be available to ordinary users.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;This change should improve security in providing end-to-end encryption
for secrets.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h3&gt;Notifications &amp;amp; Audit Impact&lt;/h3&gt;
&lt;p&gt;None, other than probably some changed notifications if this mechanism is
used instead of the regular mechanism.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Doing this extra encryption will mean that storing and retrieving secrets will
take two steps, rather than one, so that the correct transport key can be
retrieved.  This could be mitigated though by having the client cache the
transport key - especially given that transport keys change very infrequently.&lt;/p&gt;
&lt;p&gt;There will be some addtional work performed by the client, both in encrypting
and decrypting the secrets, but this is likely not to be onerous.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;Client work is required.  We will cover this in a separate spec.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;alee-3&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;redrobot (client side)&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;CR performing the following for storage using transport key:
*  Add transport_key_needed boolean to POST request flows
*  Add get_transport_key() method to SecretStore
*  Return transport key if requested.
*  Modify secret PUT to add transport_key_ref.
*  Lookup secret_store plugin associated with that transport_key
*  Modify the secret_store SecretDTO to accept an optional transport key&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CR performing the following for retrieval using transport key
* Modify secret metadata GET to add a reference to the transport key
* Add trans_wrapped_session_key to secret GET.
* Write this parameter into the secret_metadata and provide to the plugin.
* Modify the plugin to act accordingly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CR to implement fetching the transport key and end to end testing in Dogtag.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/94875"&gt;https://review.openstack.org/94875&lt;/a&gt; Add transport key as a resource (Done)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Barbican Client work&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;All new functionality and changes in the API/ secret store / Dogtag plugin
will be unit tested.  In addtion, we will perform end to end integration
tests using Dogtag as the backend.  Ideally, these end to end tests will be
made part of the gate testing, with Dogtag being installed using a Chef recipe.&lt;/p&gt;
&lt;p&gt;Also eventually, transport key functionality will be added to the dev plugin
and will therefore be tested too.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;This is a brand new feature and will need to be described in the docs.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/94875"&gt;https://review.openstack.org/94875&lt;/a&gt; Add transport key as a resource CR.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An old (since abandoned) implementation: &lt;a class="reference external" href="https://review.openstack.org/93165"&gt;https://review.openstack.org/93165&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Discussion at meetup: &lt;a class="reference external" href="https://etherpad.openstack.org/p/barbican-juno-meetup"&gt;https://etherpad.openstack.org/p/barbican-juno-meetup&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Discussion at Atlanta summit:
&lt;a class="reference external" href="https://etherpad.openstack.org/p/barbican-juno-roadmap"&gt;https://etherpad.openstack.org/p/barbican-juno-roadmap&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 10 Jul 2014 00:00:00 </pubDate></item><item><title>Introduce Oslo’s cliff as cli framework for Barbican</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/juno/introduce_cliff_to_barbican_client.html</link><description>

&lt;p&gt;Introduce cliff as a cli framework for python-barbicanclient, and, as a result
promote usage of common OpenStack libraries.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Currently the Barbican cli utilities (such as the migration script and even
the python-barbicanclient itself) rely on the argparse library, yet, their
current implementations do not provide sufficient information for their usage
in production. Usage of “standard” libraries should be encouraged in order to
make Barbican’s integration easier. On the other hand, subcommand help is
lacking, and input is not properly validated.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The proposal is to take into use cliff, which is a framework for building
command line programs introduced by Oslo. This will enable Barbican’s scripts
to have more standard outputs (akin to other OpenStack projects) and while
moving the code to the new framework, better documentation will be added to the
commands as part of the work.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;The argparse library could still be used, yet, more input validation and
documentation needs to be added.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None for the Barbican server. Barbican client input though should be properly
validated as part of the work.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;This will hopefully have a positive impact in the client’s usability, as the
main focus of this work is to make it better.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;This change takes immediate effect after it’s merged, and adds a dependency
(which is cliff) to the python-barbicanclient.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;If other developers are working with the client, it might affect their work,
since the changes are potentially big.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Replicate the current functionality of python-barbicanclient (with help
messages and subcommands) to the new framework.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Complete missing sub-command help over the new framework.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Unit tests are assumed.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 10 Jul 2014 00:00:00 </pubDate></item><item><title>Enforce content type on barbican REST API</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/juno/barbican-enforce-content-type.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/barbican-enforce-content-type"&gt;https://blueprints.launchpad.net/barbican/+spec/barbican-enforce-content-type&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Before barbican moved from falcon to pecan, content types were coerced to
application/json.  This meant that a user could use a tool such as curl,
omit the content type, and the call would succeed.  After moving to pecan,
the default content-type changed to application/x-www-form-urlencoded.
This meant that a curl request without a content type specified would
end up coming into barbican as a urlencoded string and would fail during
JSONifying.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;As a result of the move from falcon to pecan, the default content type for
requests has changed from application/json to
application/xxx-www-form-urlencoded.  That means that calls without a
content-type which used to work with the falcon implementation will
now fail with the pecan implementation.&lt;/p&gt;
&lt;p&gt;If a caller sets their content-type header to application/json then
everything works as expected.&lt;/p&gt;
&lt;p&gt;However, if a caller omits the content-type header then it now defaults to
application/xxx-www-form-urlencoded.  This means that pecan will URLencode
the request body, and that causes barbican to fail when it tries to JSONify
it.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;The proposed change is to check the content-type header on the following
types of Barbican requests, and reject any request (via pecan abort with
HTTP 415) that does not specify the correct value:&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Resource&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;HTTP Verb&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Enforced Content Types&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Secret&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;PUT&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;application/octet-stream
text/plain&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Secrets&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;application/json&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Orders&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;application/json&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Containers&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;application/json&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;TransportKeys&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;application/json&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;There are alternatives to the proposed change:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Change the content-type header to the correct value.  This would resolve
the problem described above, but could have unintended consequences as
the user’s input data would be changed from what they provided/expected.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Detect the situation where the default was taken for content-type and
compensate by:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;URL-decoding the string&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;cleanup any padding characters that may have been added&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;Users of the following resources will have to provide a valid value in
their content-type header on REST API calls as indicated below:&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Resource&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;HTTP Verb&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Required Content Types&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Secret&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;PUT&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;application/octet-stream or text/plain&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Secrets&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;application/json&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Orders&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;application/json&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Containers&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;application/json&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;TransportKeys&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;application/json&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h3&gt;Notifications &amp;amp; Audit Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Each REST call will now incur a check of the content-type.  Calls without the
correct content-type will fail with pecan.abort and HTTP 415.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Developers who use a tool such as curl will need to ensure that they pass
content-type:application/json in their HTTP headers, otherwise they will
fail with HTTP 415.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;sheyman&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;john-wood-w
arunkant-uws&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;p&gt;There are 3 work items required for this change:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;updating the barbican code to detect incorrect content types and
pecan abort with HTTP 415&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;updating the barbican documentation to describe this change and
provide recovery action&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;updating the barbican tests to validate the behavior of the new code.
This includes unit and functional tests.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;The following positive test scenarios will be needed for this proposed
change:&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Resource&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Verb&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Content-Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Expected Result&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Secret&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;PUT&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;application/octet-stream&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;success&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Secret&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;PUT&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;text/plain&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;success&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Secrets&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;application/json&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;success&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Orders&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;application/json&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;success&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Containers&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;application/json&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;success&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Transport Keys&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;application/json&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;success&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;In addition, the following negative tests will be used to verify behavior:&lt;/p&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Resource&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Verb&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Content-Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Expected Result&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Secret&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;PUT&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;none (omitted)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;HTTP 415&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Secret&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;PUT&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;application/octet-streamx&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;HTTP 415&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Secret&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;PUT&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;text/plainx&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;HTTP 415&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Secret&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;PUT&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;applicationx/octet-stream&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;HTTP 415&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Secret&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;PUT&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;textx/plain&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;HTTP 415&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Secret&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;PUT&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;application/json&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;HTTP 415&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Resource&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Verb&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Content-Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Expected Result&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Secrets&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;none (omitted)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;HTTP 415&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Secrets&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;text/plain&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;HTTP 415&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Secrets&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;application/octet-stream&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;HTTP 415&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Secrets&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;application/jsonx&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;HTTP 415&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Secrets&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;applicationx/json&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;HTTP 415&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Secrets&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;application/jsonx&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;HTTP 415&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Resource&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Verb&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Content-Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Expected Result&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Orders&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;none (omitted)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;HTTP 415&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Orders&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;text/plain&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;HTTP 415&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Orders&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;application/octet-stream&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;HTTP 415&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Orders&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;application/jsonx&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;HTTP 415&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Orders&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;applicationx/json&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;HTTP 415&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Orders&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;application/jsonx&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;HTTP 415&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Resource&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Verb&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Content-Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Expected Result&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Containers&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;none (omitted)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;HTTP 415&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Containers&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;text/plain&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;HTTP 415&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Containers&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;application/octet-stream&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;HTTP 415&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Containers&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;application/jsonx&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;HTTP 415&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Containers&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;applicationx/json&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;HTTP 415&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Containers&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;application/jsonx&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;HTTP 415&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class="docutils align-default"&gt;
&lt;thead&gt;
&lt;tr class="row-odd"&gt;&lt;th class="head"&gt;&lt;p&gt;Resource&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Verb&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Content-Type&lt;/p&gt;&lt;/th&gt;
&lt;th class="head"&gt;&lt;p&gt;Expected Result&lt;/p&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Transport Keys&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;none (omitted)&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;HTTP 415&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Transport Keys&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;text/plain&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;HTTP 415&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Transport Keys&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;application/octet-stream&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;HTTP 415&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Transport Keys&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;application/jsonx&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;HTTP 415&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-even"&gt;&lt;td&gt;&lt;p&gt;Transport Keys&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;applicationx/json&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;HTTP 415&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="row-odd"&gt;&lt;td&gt;&lt;p&gt;Transport Keys&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;POST&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;application/jsonx&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;HTTP 415&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Documentation will need to specify that the content-type header is now
required for the API/verbs shown above under “Proposed Change”.  Omitted
content-type, or content-type other than the allowed values will result
in an HTTP 415.&lt;/p&gt;
&lt;p&gt;NOTE: current documentation says that a secret PUT “should” include
the appropriate content-type.  That will have to be updated to “must”.  See
&lt;a class="reference external" href="https://github.com/cloudkeep/barbican/wiki/Application-Programming-Interface#put"&gt;https://github.com/cloudkeep/barbican/wiki/Application-Programming-Interface#put&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;The following bugs and proposed fixes led to the creation of this blueprint:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/97554"&gt;https://review.openstack.org/#/c/97554&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/99423"&gt;https://review.openstack.org/#/c/99423&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/barbican/+bug/1321555"&gt;https://bugs.launchpad.net/barbican/+bug/1321555&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://bugs.launchpad.net/barbican/+bug/1320276"&gt;https://bugs.launchpad.net/barbican/+bug/1320276&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Tue, 17 Jun 2014 00:00:00 </pubDate></item><item><title>Remove the project-id from Barbican resource URIs</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/juno/api-remove-uri-project-id.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/api-remove-uri-tenant-id"&gt;https://blueprints.launchpad.net/barbican/+spec/api-remove-uri-tenant-id&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;OpenStack projects appear to be moving away from requiring a project-id in the URI,
as this is redundant information when Keystone authentication is used.
All Barbican resource URIs includes project-id as part of their URI. This need to be
reviewed.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;All Barbican resources have a project-id in their URI. This helps to correlate the
resource with the specified tenant when no external authentication mechanism is used.&lt;/p&gt;
&lt;p&gt;However, all Barbican deployments would use Keystone to authenticate the API requests.
With Keystone, the project-id information is already obtained when the X-Auth-Token header
from the request is validated. This makes the project-id in the URI redundant.&lt;/p&gt;
&lt;p&gt;Need a solution to remove the project-id from the URI.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;All Barbican resource URIs will drop project-id from their URI. For example,
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/v1/&amp;lt;project-id&amp;gt;/secrets&lt;/span&gt;&lt;/code&gt; &lt;em&gt;will become&lt;/em&gt; &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/v1/secrets&lt;/span&gt;&lt;/code&gt;,
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/v1/&amp;lt;project-id&amp;gt;/secrets/&amp;lt;secret-ref&amp;gt;&lt;/span&gt;&lt;/code&gt; &lt;em&gt;will become&lt;/em&gt; &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;/v1/secrets/&amp;lt;secret-ref&amp;gt;&lt;/span&gt;&lt;/code&gt;
and so on.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For all successfully authenticated client requests, the project-id (a.k.a tenant-id)
would be obtained by looking up the authentication context associated with the request.
If it is not found (unscoped token), the request will be denied with a HTTP 401 error.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If no authentication mechanism has been configured with the Barbican deployment, the
client is expected to pass in a “X-Project-Id” request header, set to the desired project-id.
If this header is not passed in, the request will be denied with a HTTP 400 error. In other
words, the client is expected to spoof the data presented to Barbican by
&lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;keystone.middleware.auth_token&lt;/span&gt;&lt;/code&gt;, which Barbican trusts.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Backwards compatability note:&lt;/strong&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Once the changes proposed by this spec are in place, callers of the API should no longer
specify project-id in the URI. Otherwise, the request will be denied with a HTTP 404 error.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;All Barbican REST resources will be impacted by this change. However, this change is limited to
dropping the project-id from the uri. All other request parameters (including limit and filter
parameters) will remain the same. If Barbican is configured for unauthenticated request flow,
then &lt;code class="docutils literal notranslate"&gt;&lt;span class="pre"&gt;X-Project-Id&lt;/span&gt;&lt;/code&gt; is required to be passed by the caller.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="api"&gt;
&lt;h3&gt;API&lt;/h3&gt;
&lt;p&gt;Secrets&lt;/p&gt;
&lt;p&gt;Create Secret: POST /v1/secrets&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;

    &lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;

    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"AES key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"expiration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2014-02-28T19:14:44.180394"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"algorithm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"aes"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"bit_length"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"cbc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"payload"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"gF6+lLoF3ohA9aPRpt+6bQ=="&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"payload_content_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/octet-stream"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"payload_content_encoding"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"base64"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;201&lt;/span&gt; &lt;span class="n"&gt;Created&lt;/span&gt;

    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"secret_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:9311/v1/secrets/a8957047-16c6-4b05-ac57-8621edd0e9ee"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Two-step secret creation: PUT /v1/secrets/&amp;lt;secret-id&amp;gt;&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;plain&lt;/span&gt;

    &lt;span class="n"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;a8957047&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="n"&gt;c6&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;b05&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ac57&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;8621&lt;/span&gt;&lt;span class="n"&gt;edd0e9ee&lt;/span&gt;

    &lt;span class="s1"&gt;'mysecret'&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;201&lt;/span&gt; &lt;span class="n"&gt;Created&lt;/span&gt;

    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"secret_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:9311/v1/secrets/a8957047-16c6-4b05-ac57-8621edd0e9ee"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;List Secrets: GET /v1/secrets&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;Ok&lt;/span&gt;

    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"secrets"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ACTIVE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"updated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2013-06-28T15:23:30.668641"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"cbc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Main Encryption Key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"algorithm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"AES"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"created"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2013-06-28T15:23:30.668619"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"secret_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:9311/v1/secrets/e171bb2d-f14f-433e-84f0-3dfcac7a7311"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"expiration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2014-06-28T15:23:30.668619"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"bit_length"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"content_types"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"default"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/octet-stream"&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ACTIVE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"updated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2013-06-28T15:23:32.210474"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"cbc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Backup Key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"algorithm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"AES"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"created"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2013-06-28T15:23:32.210467"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"secret_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:9311/v1/secrets/6dba7827-c232-4a2b-8f3d-f523ca3a3f99"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"expiration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"bit_length"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"content_types"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"default"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/octet-stream"&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ACTIVE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"updated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2013-06-28T15:23:33.092660"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"PostgreSQL admin password"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"algorithm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"created"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2013-06-28T15:23:33.092635"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"secret_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:9311/v1/secrets/6dfa448d-c35a-4158-abaf-e4c249efb580"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"expiration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"bit_length"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"content_types"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"default"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"text/plain"&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="s2"&gt;"next"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:9311/v1/secrets?limit=3&amp;amp;offset=5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"previous"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:9311/v1/secrets?limit=3&amp;amp;offset=0"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Get individual secret: GET /v1/secrets/&amp;lt;secret-id&amp;gt;&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;e171bb2d&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;f14f&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;433e-84&lt;/span&gt;&lt;span class="n"&gt;f0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;dfcac7a7311&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;Ok&lt;/span&gt;

    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ACTIVE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"updated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2013-06-28T15:23:30.668641"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"cbc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Main Encryption Key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"algorithm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"AES"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"secret_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:9311/v1/secrets/e171bb2d-f14f-433e-84f0-3dfcac7a7311"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"expiration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2014-06-28T15:23:30.668619"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"bit_length"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"content_types"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"default"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/octet-stream"&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Delete individual secret: DELETE /v1/secrets/&amp;lt;secret-id&amp;gt;&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="n"&gt;DELETE&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;e171bb2d&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;f14f&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;433e-84&lt;/span&gt;&lt;span class="n"&gt;f0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;dfcac7a7311&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;204&lt;/span&gt; &lt;span class="n"&gt;No&lt;/span&gt; &lt;span class="n"&gt;Content&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Create Secret(no authentication) : POST /v1/secrets&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Project&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;

    &lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;secrets&lt;/span&gt;

    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"AES key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"expiration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2014-02-28T19:14:44.180394"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"algorithm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"aes"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"bit_length"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"cbc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"payload"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"gF6+lLoF3ohA9aPRpt+6bQ=="&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"payload_content_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/octet-stream"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"payload_content_encoding"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"base64"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;201&lt;/span&gt; &lt;span class="n"&gt;Created&lt;/span&gt;

    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"secret_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:9311/v1/secrets/a8957047-16c6-4b05-ac57-8621edd0e9ee"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Orders&lt;/p&gt;
&lt;p&gt;Create Order: POST /v1/orders&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;

    &lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;orders&lt;/span&gt;

    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"secret"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"secretname"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"algorithm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"AES"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"bit_length"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"cbc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"payload_content_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/octet-stream"&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;201&lt;/span&gt; &lt;span class="n"&gt;Created&lt;/span&gt;

    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"order_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:9311/v1/orders/a8957047-16c6-4b05-ac57-8621edd0e9ee"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Get individual order: GET /v1/orders/&amp;lt;order-id&amp;gt;&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;f9b633d8&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;fda5&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;be8&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;b42c&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="n"&gt;b2c9280289e&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;Ok&lt;/span&gt;

    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"secret"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"secretname"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"algorithm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"aes"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"bit_length"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"cbc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s2"&gt;"payload_content_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/octet-stream"&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="s2"&gt;"order_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:8080/v1/orders/f9b633d8-fda5-4be8-b42c-5b2c9280289e"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"secret_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:8080/v1/secrets/888b29a4-c7cf-49d0-bfdf-bd9e6f26d718"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ERROR"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"error_status_code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"400 Bad Request"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"error_reason"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Secret creation issue seen - content-encoding of 'bogus' not supported."&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Get list of orders per tenant: GET /v1/orders&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;orders&lt;/span&gt;


&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;Ok&lt;/span&gt;

    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"orders"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ACTIVE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"secret_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:9311/v1/secrets/bf2b33d5-5347-4afb-9009-b4597f415b7f"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"updated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2013-06-28T18:29:37.058718"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"created"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2013-06-28T18:29:36.001750"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"secret"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"secretname"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"algorithm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"aes"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"bit_length"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"cbc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"payload_content_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/octet-stream"&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="s2"&gt;"order_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:9311/v1/orders/3100078a-6ab1-4c3f-ab9f-295938c91733"&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ACTIVE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"secret_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:9311/v1/secrets/fa71b143-f10e-4f7a-aa82-cc292dc33eb5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"updated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2013-06-28T18:29:37.058718"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"created"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2013-06-28T18:29:36.001750"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"secret"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"secretname"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"algorithm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"aes"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"bit_length"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"cbc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"payload_content_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/octet-stream"&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="s2"&gt;"order_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:9311/v1/orders/30b3758a-7b8e-4f2c-b9f0-f590c6f8cc6d"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Delete individual order: DELETE /v1/orders/&amp;lt;order-id&amp;gt;&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="n"&gt;DELETE&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;e171bb2d&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;f14f&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;433e-84&lt;/span&gt;&lt;span class="n"&gt;f0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;dfcac7a7311&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;204&lt;/span&gt; &lt;span class="n"&gt;No&lt;/span&gt; &lt;span class="n"&gt;Content&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Containers&lt;/p&gt;
&lt;p&gt;Create Container: POST /v1/containers&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;

    &lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;containers&lt;/span&gt;

    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"container name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"rsa"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"secret_refs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"private_key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="s2"&gt;"secret_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"http://localhost:9311/v1/secrets/05a47308-d045-43d6-bfe3-1dbcd0c3a97b"&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"public_key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="s2"&gt;"secret_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"http://localhost:9311/v1/secrets/05a47308-d045-43d6-bfe3-1dbcd0c3a97b"&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"private_key_passphrase"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="s2"&gt;"secret_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"http://localhost:9311/v1/secrets/05a47308-d045-43d6-bfe3-1dbcd0c3a97b"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;201&lt;/span&gt; &lt;span class="n"&gt;Created&lt;/span&gt;

    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"container_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:9311/v1/containers/a8957047-16c6-4b05-ac57-8621edd0e9ee"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Get individual container: GET /v1/containers/&amp;lt;container-id&amp;gt;&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;containers&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;f9b633d8&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;fda5&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="n"&gt;be8&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;b42c&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="n"&gt;b2c9280289e&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;Ok&lt;/span&gt;

    &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"rsa container"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="s2"&gt;"secret_refs"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;
             &lt;span class="s2"&gt;"secret_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"http://localhost:9311/v1/secrets/059805d5-b400-47da-abc5-cae7286d3ede"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"private_key_passphrase"&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;
             &lt;span class="s2"&gt;"secret_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"http://localhost:9311/v1/secrets/28704f0f-3273-40d4-bc40-4de2691135ea"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"private_key"&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;
             &lt;span class="s2"&gt;"secret_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"http://localhost:9311/v1/secrets/29d89344-10ad-4f92-8aa2-adebaf7556ee"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"public_key"&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
       &lt;span class="p"&gt;],&lt;/span&gt;
       &lt;span class="s2"&gt;"container_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"http://localhost:9311/v1/containers/888b29a4-c7cf-49d0-bfdf-bd9e6f26d718"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"rsa"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Get list of containers per tenant: GET /v1/containers&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;containers&lt;/span&gt;


&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;Ok&lt;/span&gt;

    &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="s2"&gt;"total"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="s2"&gt;"containers"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;
             &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"ACTIVE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"updated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"2014-02-11T18:05:58.909411"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"generic container_updated"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"secret_refs"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                   &lt;span class="s2"&gt;"secret_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"private_key"&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                   &lt;span class="s2"&gt;"secret_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"321"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"public_key"&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                   &lt;span class="s2"&gt;"secret_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"456"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"private_key_passphrase"&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
             &lt;span class="p"&gt;],&lt;/span&gt;
             &lt;span class="s2"&gt;"created"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"2014-02-11T18:05:58.909403"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"container_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"http://localhost:9311/v1/containers/d4e06015-4f6e-4626-ac3d-4ece6621f96d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"rsa"&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;
             &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"ACTIVE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"updated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"2014-02-11T18:08:58.160557"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"generic container_updated"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"secret_refs"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                   &lt;span class="s2"&gt;"secret_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"321"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"public_key"&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                   &lt;span class="s2"&gt;"secret_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"456"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"private_key_passphrase"&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
             &lt;span class="p"&gt;],&lt;/span&gt;
             &lt;span class="s2"&gt;"created"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"2014-02-11T18:08:58.160551"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"container_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"http://localhost:9311/v1/containers/bb24fa61-0b5f-4d40-8990-846e95cd7b12"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"rsa"&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;
             &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"ACTIVE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"updated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"2014-02-11T18:25:58.198072"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"generic container_updated"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"secret_refs"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                   &lt;span class="s2"&gt;"secret_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"1df433d6-c2d4-480d-90fb-0bfd9c5da3dd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"private_key"&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                   &lt;span class="s2"&gt;"secret_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"321"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"public_key"&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                   &lt;span class="s2"&gt;"secret_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"456"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"private_key_passphrase"&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
             &lt;span class="p"&gt;],&lt;/span&gt;
             &lt;span class="s2"&gt;"created"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"2014-02-11T18:25:58.198063"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"container_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"http://localhost:9311/v1/containers/38f58696-5013-4bd6-ab2b-fbea41dc957a"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"rsa"&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;
             &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"ACTIVE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"updated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"2014-02-11T18:44:06.296957"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"generic container_updated"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"secret_refs"&lt;/span&gt;&lt;span class="p"&gt;:[&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                   &lt;span class="s2"&gt;"secret_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"1df433d6-c2d4-480d-90fb-0bfd9c5da3dd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"private_key"&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                   &lt;span class="s2"&gt;"secret_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"321"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"public_key"&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                   &lt;span class="s2"&gt;"secret_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"456"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"private_key_passphrase"&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
             &lt;span class="p"&gt;],&lt;/span&gt;
             &lt;span class="s2"&gt;"created"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"2014-02-11T18:44:06.296947"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"container_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"http://localhost:9311/v1/containers/a8d1adfd-0d36-4eb0-8762-99787eb4a7ff"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"rsa"&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
       &lt;span class="p"&gt;],&lt;/span&gt;
       &lt;span class="s2"&gt;"next"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"http://localhost:9311/v1/containers?limit=10&amp;amp;offset=10"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Delete individual container: DELETE /v1/containers/&amp;lt;container-id&amp;gt;&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Auth&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="n"&gt;DELETE&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;containers&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;e171bb2d&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;f14f&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;433e-84&lt;/span&gt;&lt;span class="n"&gt;f0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;dfcac7a7311&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;204&lt;/span&gt; &lt;span class="n"&gt;No&lt;/span&gt; &lt;span class="n"&gt;Content&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;This change will require that all requests have a valid keystone token which will
be used for authorization.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Requests without the token will be considered as unauthenticated requests.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h3&gt;Notifications &amp;amp; Audit Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Barbican python client will need to be modified to accommodate API changes.
This work could happen in parallel to the server side tasks.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Venkat Sundaram (tsv)&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Modify PecanAPI routing mechanism and remove logic that parses project-id from
the URI (&lt;strong&gt;tsv&lt;/strong&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enhance the enforce_rback decorator for the controllers to get the keystone_id
from the authentication context if it is not passed in(&lt;strong&gt;tsv&lt;/strong&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update the barbican/common/util module method hostname_for_refs to strip
project-id from the URI links returned in response body(&lt;strong&gt;tsv&lt;/strong&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Modify barbican client and replace all tenant-id references from the URI it
calls (&lt;strong&gt;tsv&lt;/strong&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enhance the tests (&lt;strong&gt;tsv&lt;/strong&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Update unit tests to drop project-id from uri.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tempest tests need to be added for functional testing&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Existing documentation has to be updated to remove the project-id from the uri.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Explain how to specify project-id when no authentication mechanism is used.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/api-remove-uri-tenant-id"&gt;https://blueprints.launchpad.net/barbican/+spec/api-remove-uri-tenant-id&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://review.openstack.org/#/c/92491/4/api-docs/keystore-api-v1-remove-tenant-from-uri-and-more.md"&gt;https://review.openstack.org/#/c/92491/4/api-docs/keystore-api-v1-remove-tenant-from-uri-and-more.md&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Mon, 16 Jun 2014 00:00:00 </pubDate></item><item><title>Barbican Spec - Barbican Consumer Registration</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/juno/api-add-container-registration.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/api-add-container-registration"&gt;https://blueprints.launchpad.net/barbican/+spec/api-add-container-registration&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Allow consumers to register as “interested parties” on Barbican Containers and
Secrets. This information would then be available when the container is
retrieved, which a client process could use to either warn about these
interested parties prior to performing a delete operation, or else use to
determine what parties to update if a new Container is created that needs to
replace an old one.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;In some workflows, multiple clients will be accessing the same Container/Secret
information in Barbican. This workflow might involve a client updating or
deleting this ‘shared’ information. If this client could check to see what
entities are interested in this information, they might be able to perform
follow on operations (such as updating or notifiying the affected entities of
the update), or else warn the user that an operation could impact other entites
(such as before performing a delete).&lt;/p&gt;
&lt;p&gt;An example workflow is when a client creates certificate information within
Barbican (which creates a Container with a unique UUID), and then shares that
Container UUID with LBaaS as part of creating a load balancer instance. LBaaS
could both retrieve the Container by UUID to get the certificate to install,
and also register itself as an interested consumer for that Container. Now if a
client wishes to delete that same Container later, they can check to see if one
or more consumers are interested in the Container first. They might choose (for
example) to remove the load balancer first, or else abort the delete process
altogether.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;Allow consumers to register their interest for a Barbican Container or Secret.&lt;/p&gt;
&lt;p&gt;This will require a new REST Pecan API sub-resource under the ‘containers’ and
‘secrets’ resource, so consumers can POST to register and DELETE to deregister
with their consumer data in the JSON body. This is detailed in the API impact
section below.&lt;/p&gt;
&lt;p&gt;We will also need two new tables in the data model for storing this consumer
data. This is detailed in the Data model impact section below.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;This could also be done without a new resource, and using query parameters like
‘register’ and ‘deregister’ on the existing GET call for a Container, but that
does not conform to a true RESTful scheme and would add side effect bahaviors
to the simple GET call.&lt;/p&gt;
&lt;p&gt;We could avoid the admin-api and instead add the functionality to the standard
user-api, restricting access using keystone roles.&lt;/p&gt;
&lt;p&gt;We could use a single generic table for the Data Model instead of one for each
entity type, but it seems to be consensus that it is worth an extra table in
order to maintain a clear ForeignKey relationship.&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;Alternatives to the entire service registration concept include the following:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;1) Keep Barbican simple and force clients to handle switching from one
Container UUID to a new one, in all the dependent consumers such as LBaaS.
Orchestration systems such as Heat might be able to handle this conversion.
However the LBaaS community is concerned that since clients would still
have access to the Containers, they could in turn delete them from under
such orchestrations. LBaaS attempts to failover to a new load balance
instance if needed would then fail, as the original Container UUID would no
longer be available.&lt;/p&gt;
&lt;p&gt;2) Allow Containers to be mutable such that certificates (for example)
could be updated without changing Container UUIDs. Barbican could then fire
off events to interest parties (like LBaaS) for them to update certificates
in load balancer instances. If new certificate is flawed however, LBaaS
would need to be able to revert back to a previous version of the
certificate. Adding versioning to Barbican would be a significant effort
with minimal benefit versus effort.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;A new model and repository will be created for ContainerConsumerMetadatum
containing the following:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;container_id (ForeignKey reference to Container.id)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;name (String, freeform data specified by the consumer, eg: “LBaaS”, “VPNaaS”)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;URL (String, resource locator for the object that depends on this entity,
eg: “&lt;a class="reference external" href="https://lbaas.myurl.net/loadbalancer"&gt;https://lbaas.myurl.net/loadbalancer&lt;/a&gt;/&amp;lt;lbid&amp;gt;”)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;A Unique constraint would be put on the combination of “container_id”, “name”,
and “URL”. An Index would be created on “container_id” and “name”.&lt;/p&gt;
&lt;p&gt;The same will be done for SecretConsumerMetadatum, with column names updated
appropriately.&lt;/p&gt;
&lt;p&gt;As this is an optional one to many relationship off of Containers/Secrets, data
migrations should not be required.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;This BP impacts both the admin API and the user API.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Changes that affect the admin API:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Need to add a new resource in the admin-api named “consumers”, supporting GET,
POST and DELETE. This would be a subresource of “containers” and “secrets”, so
we would also need to create a stub resource for “containers” and “secrets” on
the admin-api.
Example: &lt;a class="reference external" href="http://admin-api/v1/containers"&gt;http://admin-api/v1/containers&lt;/a&gt;/{container-uuid}/consumers&lt;/p&gt;
&lt;p&gt;A simple registration JSON Body would be structured like the following
using the POST method:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"LBaaS"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"URL"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"https: //lbaas.myurl.net/loadbalancer/4124/"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The response of this registration POST would be the current entity response
as available from a GET call. Hence after a client creates a Container and
hands that UUID to LBaaS (for example) to create a load balancer instance,
LBaaS will make the above POST call to the ‘consumers’ sub-resource of that
Container UUID. LBaaS would then synchronously receive the Container’s
information as if they had performed a GET call, and can then install the
certificate on the load balancer.&lt;/p&gt;
&lt;p&gt;Deregistration would use the same resource and JSON Body as the registration,
except using the DELETE method. Hence the delete would be performed by value
rather than by a specific UUID reference to a consumer entity (since the
registration UUID is never exposed to the consumer).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Changes that affect the user API:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The JSON Body for the GET response of a Container/Secret would include the
current GET response for that entity, plus a new ‘consumers’ element, that
will be structured as follows:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;current&lt;/span&gt; &lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"consumers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"LBaaS"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"URL"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"https://lbaas.myurl.net/loadbalancer/4124/"&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"LBaaS"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"URL"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"https://lbaas.myurl.net/loadbalancer/4125/"&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"VPNaaS"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"URL"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"https://vpn.myurl.net/vpn/345634/"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If significant performance degredation is observed in testing, the current
Container/Secret API could change as follows in a future CR:&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;1) The GET on the root (list) call can be modified to not return the
‘consumers’ attribute to reduce the overall size of the response message.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;This blueprint would not require changes to cryptographic resources. We might
need to impose an upper limit on the number of consumers that can be registered
per Container/Secret to prevent denial of service attacks.&lt;/p&gt;
&lt;p&gt;There is also some concern that any metadata stored on Barbican entities should
be encrypted for security, but that concern applies to much more than this
functionality, and should probably be handled as its own blueprint.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;Initially, there could be a performance impact on the GET for /containers/ and
/secrets/ (the list, not individual entities) because of an increase in the
amount of data returned. If this is significant, then consumer registration
information will only be retrieved for GETs on specific Containers/Secrets, and
not on the GET list of all Containers/Secrets.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;Developers of services that consume Barbican Containers/Secrets would use the
admin-api consumer service instead of using the standard api GET resource when
they wish to register their interest in an entity. This feature is optional
however, and would not impact current workflows.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignees:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;adam-harwell&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;vivek-jain&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;The initial implementation will consist of two CRs:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;One CR will be created for the initial implementation with Containers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A subsequent CR will be created to add this functionality to Secrets.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;There may be an additional CR for the above mentioned performance changes.&lt;/p&gt;
&lt;p&gt;There may be an additional BP/CR for encryption of this (and other) metadata.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Add unit and integration testing for the new feature.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Update API guide here:
&lt;a class="reference external" href="https://github.com/cloudkeep/barbican/wiki/Application-Programming-Interface"&gt;https://github.com/cloudkeep/barbican/wiki/Application-Programming-Interface&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://wiki.openstack.org/wiki/Neutron/LBaaS/SSL#TLS_Certificates_Management"&gt;https://wiki.openstack.org/wiki/Neutron/LBaaS/SSL#TLS_Certificates_Management&lt;/a&gt;
(At the time this was written, this wiki is still assuming Mutable Containers,
which will be corrected soon.)&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Wed, 11 Jun 2014 00:00:00 </pubDate></item><item><title>Add more types to the orders resource</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/juno/api-orders-add-more-types.html</link><description>

&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/api-orders-add-more-types"&gt;https://blueprints.launchpad.net/barbican/+spec/api-orders-add-more-types&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Barbican’s orders resource is used to generate secrets on behalf of clients.
Currently (as of Icehouse M2) only specific symmetric key secrets can be
generated. This blueprint addresses how the orders resources can be modified
to generate other useful secret types, such as asymmetric key-pairs.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem Description&lt;/h2&gt;
&lt;p&gt;Barbican is currently lacking generation support for following secret types
which is highly expected from a Key Manager:&lt;/p&gt;
&lt;p&gt;There are three main types of secret information that could be generated by
Barbican via the Orders resource:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;Key:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Symmetric encryption keys: AES, 3DES, Camellia, RC4.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Other types of keys: HMAC, byte stream&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;Asymmetric:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;RSA, DSA, EC.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Can include public and private keys, and a passphrase&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;Certificate:&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Generation by CSR signing by CA.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Generation by Barbican and its back-end plug-in using different parameters.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed Change&lt;/h2&gt;
&lt;p&gt;This is a multi phase initiative as described below:&lt;/p&gt;
&lt;p&gt;1. Enhance Barbican crypto plug-in framework to support generation of different
types of secrets. (Completed)&lt;/p&gt;
&lt;ol class="arabic simple" start="2"&gt;
&lt;li&gt;&lt;p&gt;Make appropriate changes to the Order data model to hold required parameters.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enhance Orders REST API to support Key and Asymmetric secrets.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;Enhance Orders REST API to support Certificate type secrets which includes&lt;/dt&gt;&lt;dd&gt;&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;API changes to support CSR post.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API changes to support post or certificate parameters.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Barbican core subsystem to integrate with CA.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Barbican event subsystem to emit events for certificate life-cycle.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;Barbican Order model has to be enhanced to support these requirements.
Following new fields will need to be added in the model:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;Type (String): This field will represent the order type. Allowed options are&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;key, asymmetric and certificates&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;Meta (Text): This field will hold JSON string and store all meta attributes&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;for secrets.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;container_id: An optional field depending on generated artifacts, a particular&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;type of secret can have multiple sub secrets. Such secrets requires &lt;cite&gt;Container&lt;/cite&gt; object to group
multiple secrets. e.g. Private Key, Public Key and Passphrase for a asymmetric key.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Note: Either the container_id or the existing secret_id will be filled
out once the order is ACTIVE, depending on the type of secret generated
by the order.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;The ordering resource allows for the generation of secret material by &lt;cite&gt;Barbican&lt;/cite&gt;.
The ordering object encapsulates the work flow and history for the creation of a secret.
This interface is implemented as an asynchronous process since the time to generate a
secret can vary depending on the type of secret.&lt;/p&gt;
&lt;p&gt;Resource Structure:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"--type--"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="s2"&gt;"meta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"--name--"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"algorithm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"--algorithm--"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"bit_length"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;bit_length&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"--mode--"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"pass_phrase"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"--pass_phrase--"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"expiration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"--expiration--"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"payload_content_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"--type--"&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note: Structure for meta is not yet decided for type certificate.&lt;/p&gt;
&lt;p&gt;Required Attribute:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Type of the secret, supported options are key, asymmetric
and certificate:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;meta&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Describes additional information regarding the secret:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;meta&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Human readable name for the secret:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;meta&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;algorithm&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Cryptographic algorithm type used to generate the secret. e.g. aes,
3des, hmacsha1, hmacsha256,hmacsha384, hmacsha512, rsa and dsa:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;meta&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bit_length&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The bit-length of the secret.&lt;/p&gt;
&lt;p&gt;Optional Attribute:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;meta&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mode&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The type/mode of the algorithm associated with the secret information:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;meta&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pass_phrase&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Pass phrase to be associated with secret.  Used in conjunction when
type is asymmetric:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;meta&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;expiration&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The expiration date for the secret in ISO-8601 format.
Once the secret has expired, it will no longer be returned
by the API or agent. If this field is not supplied, then
the secret has no expiration date:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;meta&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;payload_content_type&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="api"&gt;
&lt;h3&gt;API&lt;/h3&gt;
&lt;p&gt;Order&lt;/p&gt;
&lt;p&gt;Create Order: POST /{tenant_id}/orders&lt;/p&gt;
&lt;p&gt;Example 01 - Symmetric key generation:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tenant_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;orders&lt;/span&gt;

    &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="s2"&gt;"meta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"secretname"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"algorithm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"aes"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"bit_length"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"cbc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"expiration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2015-02-28T19:14:44.180394"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"payload_content_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/octet-stream"&lt;/span&gt;
       &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;201&lt;/span&gt; &lt;span class="n"&gt;Created&lt;/span&gt;

    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"order_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:9311/v1/1234/orders/daf3c6de-095f-46a8-94ec-65ec0d98eb68"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Example 02 - Asymmetric key generation:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tenant_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;orders&lt;/span&gt;

    &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"asymmetric"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="s2"&gt;"meta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"secretname"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"algorithm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"RSA"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"bit_length"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2048&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"expiration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2015-02-28T19:14:44.180394"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"payload_content_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/octet-stream"&lt;/span&gt;
       &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;201&lt;/span&gt; &lt;span class="n"&gt;Created&lt;/span&gt;

    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"order_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:9311/v1/1234/orders//a8957047-16c6-4b05-ac57-8621edd0e9ee"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Example 03 - Certificate generation:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TBD&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TBD&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;List Orders: &lt;cite&gt;GET /{tenant_id}/orders&lt;/cite&gt;&lt;/p&gt;
&lt;p&gt;List orders per tenant:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tenant_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;orders&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;

    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"orders"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ACTIVE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"secret_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:9311/v1/12345/secrets/bf2b33d5-5347-4afb-9009-b4597f415b7f"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"updated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2013-06-28T18:29:37.058718"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"created"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2013-06-28T18:29:36.001750"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"meta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"secretname"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="s2"&gt;"algorithm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"AES"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="s2"&gt;"bit_length"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="s2"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"cbc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="s2"&gt;"expiration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2015-02-28T19:14:44.180394"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="s2"&gt;"payload_content_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/octet-stream"&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="s2"&gt;"order_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:9311/v1/1234/orders/daf3c6de-095f-46a8-94ec-65ec0d98eb68"&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ACTIVE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"container_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:9311/v1/12345/containers/fa71b143-f10e-4f7a-aa82-cc292dc33eb5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"updated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2013-06-28T18:29:37.058718"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"created"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2013-06-28T18:29:36.001750"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"asymmetric"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"meta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"secretname"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="s2"&gt;"algorithm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"RSA"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="s2"&gt;"bit_length"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2048&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="s2"&gt;"expiration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2015-02-28T19:14:44.180394"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="s2"&gt;"payload_content_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/octet-stream"&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="s2"&gt;"order_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:9311/v1/1234/orders//a8957047-16c6-4b05-ac57-8621edd0e9ee"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Note: There is no change to the existing “limit” and “offset” filter parameters.&lt;/p&gt;
&lt;p&gt;Get Order: &lt;cite&gt;GET /{tenant_id}/orders/{order_id}&lt;/cite&gt;&lt;/p&gt;
&lt;p&gt;Get order by order_id:&lt;/p&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tenant_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;order_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;OK&lt;/span&gt;

   &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"asymmetric"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s2"&gt;"meta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"secretname"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="s2"&gt;"algorithm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"RSA"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="s2"&gt;"bit_length"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2048&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="s2"&gt;"expiration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2015-02-28T19:14:44.180394"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="s2"&gt;"payload_content_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"application/octet-stream"&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="s2"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"ACTIVE"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"container_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:9311/v1/12345/containers/fa71b143-f10e-4f7a-aa82-cc292dc33eb5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"updated"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2013-06-28T18:29:37.058718"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"created"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"2013-06-28T18:29:36.001750"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"order_ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:9311/v1/1234/orders//a8957047-16c6-4b05-ac57-8621edd0e9ee"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-audit-impact"&gt;
&lt;h3&gt;Notifications &amp;amp; Audit Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Barbican-python client will need to be enhanced to accommodate API changes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;p&gt;Arvind Tiwari (atiwari) is leading this feature enhancement.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Enhance crypto plug-in framework to support secret generation for
different types. (atiwari, DONE)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Data migration to add Type, Meta and container_id in the Orders Model.
(atiwari, DONE)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enhance Order REST API to support key and asymmetric order type.
(atiwari, IN_PROGRESS, &lt;a class="reference external" href="https://review.openstack.org/#/c/87405/"&gt;https://review.openstack.org/#/c/87405/&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enhance Order REST API to support certificate order type.
(TBD)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enhance Barbican python client to support key and asymmetric order type.
(TBD)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enhance Barbican python client to support certificate order type.
(TBD)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;Need to add unit testing for the new order types.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This change has to be backwards compatible by allowing the current
order contract to be used to generate symmetric keys, in addition
to the new way outlined in this blueprint.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;Order API request and response structure has to be explained in the docs.&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;&lt;a class="reference external" href="https://github.com/cloudkeep/barbican/wiki/Application-Programming-Interface#orders-resource"&gt;https://github.com/cloudkeep/barbican/wiki/Application-Programming-Interface#orders-resource&lt;/a&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Barbican WADL and developer guide will be update for this API change.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/api-orders-add-more-types"&gt;https://blueprints.launchpad.net/barbican/+spec/api-orders-add-more-types&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://etherpad.openstack.org/p/create-multi-part-rsa-secrets-with-order"&gt;https://etherpad.openstack.org/p/create-multi-part-rsa-secrets-with-order&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a class="reference external" href="https://gist.github.com/jfwood/9080109"&gt;https://gist.github.com/jfwood/9080109&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/section&gt;
</description><pubDate>Thu, 05 Jun 2014 00:00:00 </pubDate></item><item><title>Restructure project to better accommodate all plugin types</title><link>https://specs.openstack.org/openstack/barbican-specs/specs/juno/restructure-for-plugins.html</link><description>

&lt;p&gt;Include the URL of your launchpad blueprint:&lt;/p&gt;
&lt;p&gt;&lt;a class="reference external" href="https://blueprints.launchpad.net/barbican/+spec/restructure-for-plugins"&gt;https://blueprints.launchpad.net/barbican/+spec/restructure-for-plugins&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The current project structure only naturally accommodates HSM-style plugins in
the ‘crypto’ package. This blueprint accommodates all the plugin types
required by Barbican by reorganizing the project structure under a ‘plugin’
package.&lt;/p&gt;
&lt;section id="problem-description"&gt;
&lt;h2&gt;Problem description&lt;/h2&gt;
&lt;p&gt;The current project structure places the only plugin currently supported by
Barbican (used to interface with HSMs) into a ‘crypto’ package. Planning for
new Barbican features has revealed the need for new types of plugins, that are
either awkward to implement with the HSM contract (such as Dogtag or KMIP) or
else are entirely different types of plugins. The latter includes SSL
certificate workflow processing plugins, and eventing plugins. These new
plugins do not fit well into the current ‘crypto’ package, and hence Barbican
has outgrown it.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="proposed-change"&gt;
&lt;h2&gt;Proposed change&lt;/h2&gt;
&lt;p&gt;This blueprint replaces the current ‘crypto’ package with the following
package structure:&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;common/&lt;/dt&gt;&lt;dd&gt;&lt;dl class="simple"&gt;
&lt;dt&gt;resources.py  - API and Worker processes call into this module to&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;generate, store or get secrets.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;plugin_managers.py - Contains base-level stevedore plugin lookup logic as&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;needed. Extended by interfaces in plugin package.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;plugin/&lt;/p&gt;
&lt;blockquote&gt;
&lt;div&gt;&lt;dl&gt;
&lt;dt&gt;interface/   -  Stores Plugin contracts used by other Barbican packages&lt;/dt&gt;&lt;dd&gt;&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;(as abc abstracts). Also has stevedore lookup methods.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;secret_store.py -  Nate’s current data storage plugin, that handles&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;securely storing/retrieving secrets (such as Dogtag
and KMIP). Would also include a class called
SecretStorePluginManager that uses stevedore to look
up Nate’s secret store plugin implementations.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;certificates.py -  SSL certificate workflow plugins. Would also include&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;a class called CertGenerationPluginManager that uses
stevedore to look up certificate generation workflow
plugin implementations.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/dd&gt;
&lt;dt&gt;crypto/             -  Similar to the current ‘crypto’ package. Stores&lt;/dt&gt;&lt;dd&gt;&lt;blockquote&gt;
&lt;div&gt;&lt;p&gt;HSM and security-module related modules. Because
this is an ‘inner’ interface not intended to be
called from outside the plugin package, these
modules are segregated from the ‘interface’ package
above.&lt;/p&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;crypto.py        - Key and secret generation plugin for HSM-style&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;interfaces. Similar to the current
crypto/plugin.py::CryptoPluginBase interface. Would
also include a class called
SecretGenerationPluginManager that uses stevedore to
look up the symmetric/asymmetric key generation
plugins (the so called ‘second level plugin
lookup’). This logic is very similar to the current
crypto/extension_manager.py.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;p11_crypto.py    - Paul’s HSM plugin implementation.&lt;/p&gt;
&lt;p&gt;simple_crypto.py - Simple implementation of security-module plugin.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;store_crypto.py      - A secret_store.py implementation that adapts between&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;the higher-level secret_store.py interface and the
lower-level crypto.py interface. Would utilize
SecretGenerationPluginManager to locate the ‘second
level’ HSM-style plugin implementation.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;dogtag.py     -  Dogtag implementation of the secret_store.py interface.&lt;/p&gt;
&lt;p&gt;kmip.py       -  A KMIP implementation of the secret_store.py interface.&lt;/p&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;symantec.py   -  A Symantec implementation of the certificates.py&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;interface.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/div&gt;&lt;/blockquote&gt;
&lt;p&gt;This effort first introduces the new structure only. Then existing plugins are
moved over to the new structure, verifying unit tests still pass.&lt;/p&gt;
&lt;p&gt;To provide concrete context to this new structure, the following sequence
provides an example flow to store a secret after this refactoring effort:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;p&gt;A call is made to POST /secrets (using the one-step method)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The API code in barbican.api.controllers.secrets.py makes a call to…&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Common code in barbican.common.resources.py that has a line such as this:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight-default notranslate"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span/&gt;&lt;span class="n"&gt;storer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SecretStorePluginManager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getPlugin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="n"&gt;plugin_managers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;STORE_SECRET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;meta_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;storer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;store_secret&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;4. SecretStorePluginManager will look at the config file and see which plugin
is available. Initially it will be one of the implementations defined in
plugin.dogtag, plugin.kmip, or plugin.store_crypto.&lt;/p&gt;
&lt;p&gt;5. If the plugin is dogtag or kmip, then store_secret() will implemented by the
plugin code directly.&lt;/p&gt;
&lt;p&gt;6. If the plugin is the store_crypto adapter, then store_secret() will in turn
call common.plugin_manager.py to find a crypto/security-module type of plugin
(i.e. a second-stage stevedore lookup). Initially this will be either
plugin/crypto/p11_crypto.py or simple_crypto.py, and the encrypt() method will
be called on it as done now.&lt;/p&gt;
&lt;p&gt;7. The plugin returns, updates meta_data, creates the secret record and returns
the url to the user.&lt;/p&gt;
&lt;section id="alternatives"&gt;
&lt;h3&gt;Alternatives&lt;/h3&gt;
&lt;p&gt;More detailed discussion occurred on this etherpad:
&lt;a class="reference external" href="https://etherpad.openstack.org/p/extension-manager"&gt;https://etherpad.openstack.org/p/extension-manager&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;An original approach discussed elevating the interfaces to top level Barbican
packages. However, that would place them at the same level as the ‘common’,
‘api’ and ‘task’ packages (for example) which would make the plugin source
code locations harder to locate. Hence it seemed that centralizing all plugins
under a clear ‘plugin’ package would provide this proper delineation relative
to the rest of the source code. Under the ‘plugin’ package, the structure is
designed to organize interface, default and external modules.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="data-model-impact"&gt;
&lt;h3&gt;Data model impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="rest-api-impact"&gt;
&lt;h3&gt;REST API impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="security-impact"&gt;
&lt;h3&gt;Security impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="notifications-impact"&gt;
&lt;h3&gt;Notifications impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-end-user-impact"&gt;
&lt;h3&gt;Other end user impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="performance-impact"&gt;
&lt;h3&gt;Performance Impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="other-deployer-impact"&gt;
&lt;h3&gt;Other deployer impact&lt;/h3&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="developer-impact"&gt;
&lt;h3&gt;Developer impact&lt;/h3&gt;
&lt;p&gt;This first phase of this change will not be impactful as it sets up the new
folder structure only. Once existing plugin implementations are moved to the
new structure, pending CRs will be impacted as the file structure has changed.
We should be able to sequence this change with our contributors however.&lt;/p&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="implementation"&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;section id="assignee-s"&gt;
&lt;h3&gt;Assignee(s)&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;Primary assignee:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;john-wood-w&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Other contributors:&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;alee-3
rellerreller&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;section id="work-items"&gt;
&lt;h3&gt;Work Items&lt;/h3&gt;
&lt;dl class="simple"&gt;
&lt;dt&gt;CR #1 - Add new structure in parallel to current structure, should not impact&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;current code base.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;CR #2 - Move existing plugins over to the new structure, including updating&lt;/dt&gt;&lt;dd&gt;&lt;p&gt;api/ and tasks/ modules to refer to the new locations, and then
verifying unit tests still pass.&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;/section&gt;
&lt;/section&gt;
&lt;section id="dependencies"&gt;
&lt;h2&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;None.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="testing"&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;Current unit testing will need to be changed to reference the new location of
items in the revised project structure.&lt;/p&gt;
&lt;/section&gt;
&lt;section id="documentation-impact"&gt;
&lt;h2&gt;Documentation Impact&lt;/h2&gt;
&lt;p&gt;Update this wiki section, and the sections thereafter it:
&lt;a class="reference external" href="https://github.com/cloudkeep/barbican/wiki/Developer-Guide-for-Contributors#detailed-explanation"&gt;https://github.com/cloudkeep/barbican/wiki/Developer-Guide-for-Contributors#detailed-explanation&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
&lt;section id="references"&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;p&gt;More detailed discussion occurred on this etherpad:
&lt;a class="reference external" href="https://etherpad.openstack.org/p/extension-manager"&gt;https://etherpad.openstack.org/p/extension-manager&lt;/a&gt;&lt;/p&gt;
&lt;/section&gt;
</description><pubDate>Thu, 05 Jun 2014 00:00:00 </pubDate></item></channel></rss>