node package manager

smartdc-auth

SmartDataCenter Authentication Library

Joyent SmartDC Authentication Library

Utility functions to sign http requests to SmartDC services.

var fs = require('fs');
var auth = require('smartdc-auth');

var signer = auth.privateKeySigner({
      key: fs.readFileSync(process.env.HOME + '/.ssh/id_rsa', 'utf8'),
      user: process.env.SDC_CLI_ACCOUNT
});

Authentication to SmartDC is built on top of Joyent's http-signature specification. In most situations, you will only need to sign the value of the HTTP Date header using your SSH private key; doing this allows you to create shell functions to interact with SmartDC (see below). All requests to SmartDC require an HTTP Authorization header where the scheme is Signature. Full details are available in the http-signature specification, but a simple form is:

Authorization: Signature keyId="/:login/keys/:fingerprint",algorithm="rsa-sha256" $base64_signature

The keyId for SmartDC is always /$your_joyent_login/keys/$ssh_fingerprint, and the supported algorithms are: rsa-sha1, rsa-sha256 and dsa-sha1. You then just append the base64 encoded signature.

When creating a smartdc client, you'll need to pass in a callback function for the sign parameter. smartdc-auth ships with three constructors that return such functions, which may suit your need: cliSigner, privateKeySigner and sshAgentSigner.

A basic signer which signs using a given PEM (PKCS#1) format private key only. Ideal for simple use cases where the key is stored in a file on the filesystem ready for use.

  • options: an Object containing properties:
    • key: a String, PEM-format (PKCS#1) private key, for any supported algorithm
    • user: a String, SDC login name to be used in the full keyId, above
    • subuser: an optional String, SDC sub-user login name
    • keyId: optional String, the fingerprint of the key (not the same as the full keyId given to the server). Ignored unless it does not match the given key, then an Error will be thrown.

Signs requests using a key that is stored in the OpenSSH agent. Opens and manages a connection to the current session's agent during operation.

  • options: an Object containing properties:
    • keyId: a String, fingerprint of the key to retrieve from the agent
    • user: a String, SDC login name to be used
    • subuser: an optional String, SDC sub-user login name
    • sshAgentOpts: an optional Object, any additional options to pass through to the SSHAgent constructor (eg timeout)

Signs requests using a key located either in the OpenSSH agent, or found in the filesystem under $HOME/.ssh (or its equivalent on your platform).

This is generally intended for use with CLI utilities (eg the sdc-listmachines tool and family), hence the name.

  • options: an Object containing properties:
    • keyId: a String, fingerprint of the key to retrieve or find
    • user: a String, SDC login name to be used
    • subuser: an optional String, SDC sub-user login name
    • sshAgentOpts: an optional Object, any additional options to pass through to the SSHAgent constructor (eg timeout)
    • algorithm: DEPRECATED, an optional String, the signing algorithm to use. If this does not match up with the algorithm of the key (once it is located), an Error will be thrown.

(The algorithm option is deprecated as its backwards-compatible behaviour is to apply only to keys that were found on disk, not in the SSH agent. If you have a compelling use case for a replacement for this option in future, please open an issue on this repo).

The keyId fingerprint does not necessarily need to be the exact format (hex MD5) as sent to the server -- it can be in any fingerprint format supported by the sshpk library.

As of version 2.0.0, an invalid fingerprint (one that can never match any key, because, for example, it contains invalid characters) will produce an exception immediately rather than returning a sign function.

Note that the cliSigner and sshAgentSigner are not suitable for server applications, or any other system where the performance degradation necessary to interact with SSH is not acceptable; put another way, you should only use it for interactive tooling, such as the CLI that ships with node-smartdc.

Should you wish to write a custom plugin, the expected implementation of the sign callback is a function of the form function (string, callback). string is generated by node-smartdc (typically the value of the Date header), and callback is of the form function (err, object), where object has the following properties:

{
    algorithm: 'rsa-sha256',   // the signing algorithm used
    keyId: '7b:c0:5c:d6:9e:11:0c:76:04:4b:03:c9:11:f2:72:7f', // key fingerprint
    signature: $base64_encoded_signature,  // the actual signature
    user: 'mark'   // the user to issue the call as.
}

Use-cases where you would need to write your own signer are things like signing with a smart-card or other HSM, making remote calls to a central system, etc.

MIT.

See https://github.com/joyent/node-smartdc-auth/issues.