Azure Key Vault enables Microsoft Azure applications and users to store and use several types of secret/key data:
AzureKeyVault is an R package for working with the Key Vault service. It provides both a client interface, to access the contents of the vault, and a Resource Manager interface for administering the Key Vault itself.
AzureKeyVault extends the AzureRMR package to handle key vaults. In addition to creating and deleting vaults, it provides methods to manage access policies for user and service principals.
# create a key vault
rg <- AzureRMR::get_azure_login()$
get_subscription("sub_id")$
get_resource_group("rgname")
kv <- rg$create_key_vault("mykeyvault")
# list current principals (by default includes logged-in user)
kv$list_principals()
# get details for a service principal
svc <- AzureGraph::get_graph_login()$
get_service_principal("app_id")
# give the service principal read-only access to vault keys and secrets
kv$add_principal(svc,
key_permissions=c("get", "list", "backup"),
secret_permissions=c("get", "list", "backup"),
certificate_permissions=NULL,
storage_permissions=NULL)
The client interface is R6-based. To instantiate a new client object,
call the key_vault
function. This object includes
sub-objects for interacting with keys, secrets, certificates and managed
storage accounts.
vault <- key_vault("https://mykeyvault.vault.azure.net")
# can also be done from the ARM resource object
vault <- kv$get_endpoint()
Key Vault supports RSA and elliptic curve (ECDSA) asymmetric
encryption keys. The keys
component of the client object
provides methods for managing keys:
create
: Create a new key, or a new version of an
existing key.import
: Import a key from a PEM file.get
: Retrieve an existing key.list
: List all keys in the vault.delete
: Delete a key.backup
: Return a base64-encoded blob representing the
key.restore
: Use a blob obtained by the backup
method to restore a key.do_operation
: Carry out arbitrary REST operations on
keys. Used by the above methods.In turn, an individual key is represented by an object of class
stored_key
. This has the following methods:
list_versions
: List the available versions for this
key.set_version
: Set the version of the key to use. The
default is to use the most recently created version.encrypt
: Encrypt a character string or raw vector,
producing a base64-encoded ciphertext string.decrypt
: Decrypt a ciphertext string, producing either
a character string or raw vector. The inverse operation of
encrypt
.sign
: Sign a hashed digest.verify
: Verify the signature of a hash. The inverse
operation of sign
.wrap
: Wrap a symmetric key. This is technically the
same as encrypting it, but is provided as a distinct operation to allow
more granular management of permissions.unwrap
: Unwrap a wrapped key. The inverse operation of
wrap
.The key object contains the public key component in the
key
field, as a parsed JSON web key. Note that Azure Key
Vault does not provide access to the private key component.
# create a new RSA key with 4096-bit key size
vault$keys$create("newkey", type="RSA", rsa_key_size=4096)
key <- vault$keys$get("newkey")
# encrypting and decrypting
plaintext <- "super secret"
ciphertext <- key$encrypt(plaintext)
decrypted_text <- key$decrypt(ciphertext, as_raw=FALSE)
plaintext == decrypted_text
#> [1] TRUE
# signing and verifying
dig <- openssl::sha256(charToRaw(plaintext))
sig <- key$sign(dig)
key$verify(sig, dig)
#> [1] TRUE
# exporting the public key component, using the jose and openssl packages
pubkey <- key$key
openssl::write_pem(jose::read_jwk(pubkey), "pubkey.pem")
# importing a key generated by openssl
sslkey <- openssl::rsa_keygen()
vault$keys$import("sslkey", sslkey)
# importing a key from a file
openssl::write_pem(sslkey, "sslkey.pem")
vault$keys$import("sslkeyfromfile", "sslkey.pem")
Key Vault allows you to store confidential information such as
passwords, database connection strings, tokens, API keys, and so on. The
secrets
component of the client object provides methods for
managing generic secrets:
create
: Create a new secret, or a new version of an
existing secret.get
: Retrieve an existing secret.list
: List all secrets in the vault.delete
: Delete a secret.backup
: Return a base64-encoded blob representing the
secret.restore
: Use a blob obtained by the backup
method to restore a secret.do_operation
: Carry out arbitrary REST operations on
secrets. Used by the above methods.An individual secret is represented by an object of class
stored_secret
. Unlike a key, a secret is essentially just
data, so the object does not provide any operations. It has the
following methods for managing secret versions:
list_versions
: List the available versions for this
secret.set_version
: Set the version of the secret to use. The
default is to use the most recently created version.The secret itself is in the value
field of the object,
of class secret_value
. This class has a print
method that hides the value, to help guard against shoulder-surfing.
Note that this will not stop a determined attacker; as a general rule,
you should minimise assigning secrets or passing them around your R
environment. If you want the raw string value itself, eg when passing it
to jsonlite::toJSON
or other functions which do not accept
arbitrary object classes as inputs, use unclass
to strip
the class attribute first.
The certificates
component provides methods for working
with SSL/TLS authentication certificates:
create
: Create a new certificate, or a new version of
an existing certificate. The default is to create a self-signed
certificate.import
: Import a certificate from a PFX file.get
: Retrieve an existing certificate.list
: List all certificates in the vault.delete
: Delete a certificate.backup
: Return a base64-encoded blob representing the
certificate.restore
: Use a blob obtained by the backup
method to restore a certificate.set_contacts
: Set the email address(es) to contact when
a certificate is due for renewal.get_contacts
: Get the email address(es) of the
contacts.add_issuer
: Adds the details for an issuer (certificate
authority).get_issuer
: Retrieve the details for an issuer.remove_issuer
: Removes the details for an issuer.list_issuers
: Lists the issuers available to this
vault.do_operation
: Carry out arbitrary REST operations on
certificates. Used by the above methods.An individual certificate is represented by an object of class
stored_certificate
. This has the following methods:
list_versions
: List the available versions for this
certificate.set_version
: Set the version of the certificate to use.
The default is to use the most recently created version.export
: Export the certificate as either a PEM or PFX
file (the format is fixed at certificate creation).export_cer
: Export the certificate public key as a CER
file.sign
: Sign a hashed digest.verify
: Verify a signature against a digest.set_policy
: Sets the policy for a certificate, ie the
authentication details.get_policy
: Retrieve the policy for a certificate.# create a new self-signed certificate (will also create an associated key and secret)
cert <- vault$certificates$create("newcert",
subject="CN=example.com",
x509=cert_x509_properties(dns_names="example.com"))
# import a certificate from a PFX file
vault$certificates$import("importedcert", "mycert.pfx")
# export the certificate as a PEM file
cert$export("newcert.pem")
# to export as a PFX file, set the 'format' argument at cert creation
newcert2 <- vault$certificates$create("newcert2",
subject="CN=example.com",
format="pfx")
newcert2$export("newcert2.pfx")
Note that exporting a certificate to a file should not be done unless absolutely necessary, as the point of using Key Vault is to avoid having to save sensitive data on a local machine.
The AzureAuth package is able to make use of certificates stored in Key Vault to authenticate with Azure Active Directory. Here is some example code to do so. The app (client) in question needs to be setup with the certificate public key; we create the app via the AzureGraph package and pass it the key.
## create a registered app in Azure Active Directory with cert credentials
gr <- AzureGraph::get_graph_login()
certapp <- gr$create_app("certapp", password=FALSE, certificate=cert$cer)
# authenticate using data in Key Vault
AzureAuth::get_azure_token("resource_url", "mytenant", certapp$properties$appId,
certificate=cert)
Key Vault can be configured to manage access to an Azure Storage
Account, by automatically regenerating access keys and saving
commonly-used access patterns as shared access signature (SAS)
templates. The storage
component of the client object
provides methods for working with managed accounts:
add
: Add a new storage account.get
: Retrieve an existing account.list
: List all storage accounts in the vault.remove
: Stop managing a storage account.backup
: Return a base64-encoded blob representing the
storage account.restore
: Use a blob obtained by the backup
method to restore an account.do_operation
: Carry out arbitrary REST operations on
accounts. Used by the above methods.An individual certificate is represented by an object of class
stored_account
, which has the following methods. Note that
unlike the other types of objects, storage accounts are not
versioned.
regenerate_key
: Manually regenerate an access key.create_sas_definition
: Create a SAS definition, from
which an actual SAS can be obtained.get_sas_definition
: Retrieve an existing SAS
definition.delete_sas_definition
: Delete a SAS definition.list_sas_definitions
: List existing SAS
definitions.show_sas
: Get a SAS from a definition.# get the storage account details
library(AzureStor)
res <- AzureRMR::get_azure_login()$
get_subscription("sub_id")$
get_resource_group("rgname")$
get_storage_account("mystorageacct")
# add a managed storage account
stor <- vault$storage$add("mystorage", res, "key1")
# Creating a new SAS definition
today <- Sys.time()
sasdef <- res$get_account_sas(expiry=today + 7*24*60*60, services="b", permissions="rw")
stor$create_sas_definition("newsas", sasdef, validity_period="P15D")
stor$show_sas("newsas")
For more information, see the official Key Vault documentation.