package ca import ( "fmt" "os" "github.com/pkg/errors" "github.com/urfave/cli" "github.com/smallstep/certificates/api" "github.com/smallstep/certificates/pki" "github.com/smallstep/cli-utils/command" "github.com/smallstep/cli-utils/errs" "github.com/smallstep/cli-utils/fileutil" "go.step.sm/crypto/pemutil" "golang.org/x/crypto/ssh" "github.com/smallstep/cli/flags" "github.com/smallstep/cli/utils" "github.com/smallstep/cli/utils/cautils" ) func tokenCommand() cli.Command { return cli.Command{ Name: "token", Action: command.ActionFunc(tokenAction), Usage: "generate an OTT granting access to the CA", UsageText: `**step ca token** [--**kid**=] [--**issuer**=] [**--cert-not-before**=] [**--cert-not-after**=] [**--not-before**=] [**--not-after**=] [**--password-file**=] [**--provisioner-password-file**=] [**--output-file**=] [**--kms**=uri] [**--key**=] [**--san**=] [**--offline**] [**--revoke**] [**--x5c-cert**=] [**--x5c-key**=] [**--x5c-insecure**] [**--sshpop-cert**=] [**--sshpop-key**=] [**--cnf**=] [**--cnf-file**=] [**--ssh**] [**--host**] [**--principal**=] [**--k8ssa-token-path**=] [**--ca-url**=] [**--root**=] [**--context**=] [**--set**=] [**--set-file**=]`, Description: `**step ca token** command generates a one-time token granting access to the certificates authority. ## POSITIONAL ARGUMENTS : The Common Name, DNS Name, or IP address that will be set by the certificate authority. When there are no additional Subject Alternative Names configured (via the --san flag), the subject will be added as the only element of the 'sans' claim on the token. ## EXAMPLES Most of the following examples assumes that **--ca-url** and **--root** are set using environment variables or the default configuration file in <$STEPPATH/config/defaults.json>. Get a new token for a DNS. Because there are no Subject Alternative Names configured (via the '--san' flag), the 'sans' claim of the token will have a default value of ['internal.example.com']: ''' $ step ca token internal.example.com ''' Get a new token for a 'Revoke' request: ''' $ step ca token --revoke 146103349666685108195655980390445292315 ''' Get a new token for an IP address. Because there are no Subject Alternative Names configured (via the '--san' flag), the 'sans' claim of the token will have a default value of ['192.168.10.10']: ''' $ step ca token 192.168.10.10 ''' Get a new token with custom Subject Alternative Names. The value of the 'sans' claim of the token will be ['1.1.1.1', 'hello.example.com'] - 'foobar' will not be in the 'sans' claim unless explicitly configured via the '--san' flag: ''' $ step ca token foobar --san 1.1.1.1 --san hello.example.com ''' Get a new token that expires in 30 minutes: ''' $ step ca token --not-after 30m internal.example.com ''' Get a new token that becomes valid in 30 minutes and expires 5 minutes after that: ''' $ step ca token --not-before 30m --not-after 35m internal.example.com ''' Get a new token with a confirmation claim to enforce a given CSR fingerprint: ''' $ step certificate fingerprint --format base64-url-raw internal.csr PJLNhtQoBE1yGN_ZKzr4Y2U5pyqIGiyyszkoz2raDOw $ step ca token --cnf PJLNhtQoBE1yGN_ZKzr4Y2U5pyqIGiyyszkoz2raDOw internal.smallstep.com ''' Get a new token with a confirmation claim to enforce the use of a given CSR: ''' step ca token --cnf-file internal.csr internal.smallstep.com ''' Get a new token signed with the given private key, the public key must be configured in the certificate authority: ''' $ step ca token internal.smallstep.com --key token.key ''' Get a new token for a specific provisioner kid, ca-url and root: ''' $ step ca token internal.example.com \ --kid 4vn46fbZT68Uxfs9LBwHkTvrjEvxQqx-W8nnE-qDjts \ --ca-url https://ca.example.com \ --root /path/to/root_ca.crt ''' Get a new token using the simple offline mode, requires the configuration files, certificates, and keys created with **step ca init**: ''' $ step ca token internal.example.com --offline ''' Get a new token using the offline mode with all the parameters: ''' $ step ca token internal.example.com \ --offline \ --kid 4vn46fbZT68Uxfs9LBwHkTvrjEvxQqx-W8nnE-qDjts \ --issuer you@example.com \ --key provisioner.key \ --ca-url https://ca.example.com \ --root /path/to/root_ca.crt ''' Get a new token for a 'Revoke' request: ''' $ step ca token --revoke 146103349666685108195655980390445292315 ''' Get a new token in offline mode for a 'Revoke' request: ''' $ step ca token --offline --revoke 146103349666685108195655980390445292315 ''' Get a new token for an SSH user certificate: ''' $ step ca token max@smallstep.com --ssh ''' Get a new token for an SSH host certificate: ''' $ step ca token my-remote.hostname --ssh --host ''' Get a new token with a confirmation claim to enforce the use of a given public key: ''' step ca token --ssh --host --cnf-file internal.pub internal.smallstep.com ''' Generate a renew token and use it in a renew after expiry request: ''' $ TOKEN=$(step ca token --x5c-cert internal.crt --x5c-key internal.key --renew internal.example.com) $ curl -X POST -H "Authorization: Bearer $TOKEN" https://ca.example.com/1.0/renew ''' Generate a JWK provisioner token using a key in a YubiKey: ''' $ step ca token --kms yubikey:pin-value=123456 --key yubikey:slot-id=82 internal.example.com ''' Generate an X5C provisioner token using a certificate in a YubiKey. Note that a YubiKey does not support storing a certificate bundle. To make it work, you must add the intermediate and the root in the provisioner configuration: ''' $ step ca token --kms yubikey:pin-value=123456 \ --x5c-cert yubikey:slot-id=82 --x5c-key yubikey:slot-id=82 \ internal.example.com ''' Generate a token with custom data in the "user" claim. The example below can be accessed in a template as **.Token.user.field**, rendering to the string "value". This is distinct from **.Insecure.User**: any attributes set using this option are added to a claim named "user" in the signed JWT produced by this command. This data may therefore be considered trusted (insofar as the token itself is trusted). ''' $ step ca token --set field=value internal.example.com '''`, Flags: []cli.Flag{ provisionerKidFlag, cli.StringSliceFlag{ Name: "san", Usage: `Add Subject Alternative Name(s) (SANs) that should be authorized. A certificate signing request using this token must match the complete set of SANs in the token 1:1. Use the '--san' flag multiple times to configure multiple SANs.`, }, cli.StringSliceFlag{ Name: "principal,n", Usage: `Add the principals (user or host s) that the token is authorized to request. The signing request using this token won't be able to add extra names. Use the '--principal' flag multiple times to configure multiple principals.`, }, sshHostFlag, flags.CaConfig, flags.Force, cli.StringFlag{ Name: "not-before", Usage: `The when the token's validity period starts. If a