On Tue, Sep 14, 2010 at 4:32 PM, Paul Berry <[email protected]> wrote:
> Hello all--
> I'm working with Jesse Wolfe to design a back-end REST API for the
> features of the "puppet cert" command-line tool.  This is a first cut
> at a proposed interface.  I'd appreciate comments about whether this
> is a good way to go.

Can we make sure we change all references to 'hostnames' to instead be
'certname' ?

There are quite a few of us who don't use hostnames as our certnames.

more thoughts later.

> Thanks,
> Paul
>
> =====
>
>
> Motivation
> ==========
> Most of Puppet's major components are either exposed through the REST
> API, or implemented internally using the indirector.  This allows the
> components to be controlled from a separate application (possibly on a
> remote machine) such as Puppet Dashboard.  In addition it allows
> advanced customers to connect the components of Puppet together in new
> and unexpected ways to meet their needs.  A major exception to this is
> the "CertificateAuthority" component, which allows the Puppet master
> to manage, sign, and revoke the certificates that agents use to
> authenticate themselves.  It would be useful to have a REST API for
> the certificate authority so that a new client machine could be
> provisioned without having to execute any command-line operations on
> the master.
>
>
> Scope
> =====
> This proposal adds functionality to the "puppet master" application,
> when used in the default configuration where it doubles as a
> certificate authority.  It allows a suitably authenticated client to
> use the REST API to perform all the actions available through "puppet
> cert", except for "--generate".  The client need not have access to an
> OpenSSL library to perform these actions.  The interface does not
> compromise the security of the certificate authority's private key.
> Access to this feature will be disabled by default, and can be enabled
> using Puppet's standard "authconfig" mechanism.
>
>
> API
> ===
> certificate_status and certificate_statuses
> -------------------------------------------
> To retrieve information about the status of the host called
> <hostname>, issue a GET request to
> https://<master>/<environment>/certificate_status/<hostname>.  If the
> hostname is recognized, this returns a JSON hash object of the form:
> {'state': <state>, 'hostname': <hostname>,
>  'fingerprint': <fingerprint>, 'error_message': <error_message>}
> <state> is one of:
> - 'requested' if the host has sent the server a certificate request
>   but no certificate has been issued.
> - 'signed' if a valid certificate exists for the host.
> - 'revoked' if a certificate exists for the host but has been revoked.
> - 'invalid' the host fails validation for some reason other than the
>   certificate having been revoked.
> <hostname> is the fully qualified domain name of the host.
> <fingerprint> is the fingerprint of the host's certificate or
> certificate request, as a string
> (e.g. "67:70:3E:E8:D9:75:29:F7:67:87:0E:A7:70:EE:02:80").  The default
> digest algorithm for the fingerprint is MD5.  To select another
> digest, add the parameter "?digest=<digest>" to the query string.  All
> digests supported by Ruby's OpenSSL::Digest class are permitted.
> <error_message> is a string saying why the host failed verification
> (if the host is in the 'revoked' or 'invalid' state).  Otherwise it is
> the empty string.
> This takes the place of the "puppet cert" options "--verify",
> "--fingerprint", and "--digest".
>
>
> To retrieve information about the status of multiple hosts, issue a
> GET request to
> https://<master>/<environment>/certificate_statuses/<hostname_pattern>.
> This returns JSON list object containing JSON hashes of the form
> described above, for all known hosts that match <hostname_pattern>.
> <hostname_pattern> may be "*" to match all hosts.
> To restrict the search to just hosts that are awaiting certificates,
> add the parameter "?restrict=waiting" to the query string.  To
> restrict the search to just hosts that have signed certificates, add
> the parameter "?restrict=signed".
> This takes the place of the "puppet cert" option "--list".
>
>
> To cause the master to sign or revoke a certificate for a given host,
> issue a PUT request to
> https://<master>/<environment>/certificate_status/<hostname>, and send
> the following JSON data:
> {'state': <desired_state>}
> <desired_state> is one of:
> - 'signed': causes the master to sign a certificate for the given
>   host.  The host must be in the 'requested' state for this to
>   succeed.
> - 'revoked': causes the master to revoke a certificate for the given
>   host.  The host must be in the 'signed' state for this to succeed.
> (Other hash elements, if present, are ignored).
> This takes the place of the "puppet cert" options "--sign" and
> "--revoke".
>
>
> To cause the master to discard certificate information for a given
> host, issue a DELETE request to
> https://<master>/<environment>/certificate_status/<hostname>.
> This takes the place of the "puppet cert" option "--clean".
>
>
> certificate and certificate_request
> -----------------------------------
> The existing REST APIs for
> https://<master>/<environment>/certificate/<hostname> and
> https://<master>/<environment>/certificate_request/<hostname> (which
> are already used internally for exchanging certificates and requests
> between master and agent) are extended to support a human-readable
> text format.  This format is only supported for reading.  This takes
> the place of the "puppet cert" option "--print", and uses the same
> format.
>
>
> Not supported
> -------------
> The remaining action supported by "puppet cert" is "--generate".  This
> action generates the host's public/private key pair on the master,
> with the understanding that the user will manually copy the generated
> key pair to the client.  Since a manual copy is necessary in order for
> "--generate" to be useful, it doesn't make sense to provide a REST API
> that allows a user to invoke it from a remote machine.
>
>
> IMPLEMENTATION
> ==============
> To implement the new API we'll need to add a new model class
> Puppet::SSL::CertificateState, and a new indirection
> "certificate_status".  The model class will be a thin wrapper for the
> four properties described above (status, hostname, fingerprint, and
> error_message).  We'll add a "CA" indirector terminus which is able to
> create these objects in response to find() and search() methods, is
> able to sign and revoke certificates in response to the save() method,
> and is able to delete certificates and requests in response to the
> destroy() method.
> In addition, we'll need to add new formatters for
> Puppet::SSL::Certificate and Puppet::SSL::CertificateRequest to
> support the human-readable text format.
> The existing code for "puppet cert" will be re-worked to use the new
> model class internally, so that the same code paths are exercised
> whether or not the customer is using the REST API.
>
>
> SECURITY
> ========
> The new REST API for "certificate_status" will not be mentioned by the
> default configuration in Puppet::Network::RestAuthConfig, so it will
> be disabled by default.  Users who want to enable it can do so, and
> can set access controls for it, using the standard "auth.conf"
> mechanism.
> The only parts of the REST API that are a potential security risk for
> users are the "save" and "destroy" methods for "certificate_status".
> These should be enabled with care, since they can be used to allow new
> machines to be managed by the Puppet master, or to stop old machines
> from being managed by the Puppet master.
> The other parts of the REST API (the "find" and "search" methods of
> "certificate_status", and the new format for "certificate" and
> "certificate_request") don't expose any additional security holes,
> since they merely automate what a client with access to OpenSSL could
> already do with the certificates published by the puppet master.
> None of the proposed APIs exposes any private keys.
>
> --
> You received this message because you are subscribed to the Google Groups
> "Puppet Developers" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to
> [email protected].
> For more options, visit this group at
> http://groups.google.com/group/puppet-dev?hl=en.
>



-- 
nigel

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Developers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/puppet-dev?hl=en.

Reply via email to