Title: | Share Sensitive Information in R Packages |
---|---|
Description: | Allow sharing sensitive information, for example passwords, 'API' keys, etc., in R packages, using public key cryptography. |
Authors: | Gábor Csárdi [aut, cre], Andrie de Vries [aut] |
Maintainer: | Gábor Csárdi <[email protected]> |
License: | MIT + file LICENSE |
Version: | 1.1.0.9000 |
Built: | 2024-12-21 03:09:18 UTC |
Source: | https://github.com/gaborcsardi/secret |
Allow sharing sensitive information, for example passwords, API keys, or other information in R packages, using public key cryptography.
A vault is a directory, typically inside an R package, that stores a number of secrets. Each secret is shared among a group of users. Users are identified using their public keys.
The package implements the following operations:
Vault:
Creating a vault folder: create_vault()
Creating a package vault: create_package_vault()
User management:
Adding a user: add_user()
, add_github_user()
.
Deleting a user: delete_user()
.
Listing users: list_users()
.
Keys:
Reading local private key: local_key()
Secrets:
Adding a secret: add_secret()
.
Retrieving a secret: get_secret()
.
Updating a secret: update_secret()
.
Deleting a secret: delete_secret()
.
List secrets: list_secrets()
.
Sharing a secret: share_secret()
. Query or set the set of
users that have access to a secret.
Unsharing a secret: unshare_secret()
Gábor Csárdi and Andrie de Vries
On GitHub, a user can upload multiple keys. This function will download the first key by default, but you can change this
add_github_user(github_user, email = NULL, vault = NULL, i = 1)
add_github_user(github_user, email = NULL, vault = NULL, i = 1)
github_user |
User name on GitHub. |
email |
Email address of the github user. If NULL, constructs an
email as |
vault |
Vault location (starting point to find the vault).
To create a vault, use
If the starting point is a vault, that is used. Otherwise, if the
starting point is in a package tree, the |
i |
Integer, indicating which GitHub key to use (if more than one GitHub key exists). |
Other user functions:
add_travis_user()
,
add_user()
,
delete_user()
,
list_users()
## Not run: vault <- file.path(tempdir(), ".vault") create_vault(vault) add_github_user("hadley", vault = vault) list_users(vault = vault) delete_user("github-hadley", vault = vault) ## End(Not run)
## Not run: vault <- file.path(tempdir(), ".vault") create_vault(vault) add_github_user("hadley", vault = vault) list_users(vault = vault) delete_user("github-hadley", vault = vault) ## End(Not run)
By default, the newly added secret is not shared with other
users. See the users argument if you want to change this.
You can also use share_secret()
later, to specify the users that
have access to the secret.
add_secret(name, value, users, vault = NULL)
add_secret(name, value, users, vault = NULL)
name |
Name of the secret, a string that can contain alphanumeric characters, underscores, dashes and dots. |
value |
Value of the secret, an arbitrary R object that
will be serialized using |
users |
Email addresses of users that will have access to the
secret. (See |
vault |
Vault location (starting point to find the vault).
To create a vault, use
If the starting point is a vault, that is used. Otherwise, if the
starting point is in a package tree, the |
Other secret functions:
delete_secret()
,
get_secret()
,
list_owners()
,
list_secrets()
,
local_key()
,
share_secret()
,
unshare_secret()
,
update_secret()
## Not run: # The `secret` package contains some user keys for demonstration purposes. # In this example, Alice shares a secret with Bob using a vault. keys <- function(x){ file.path(system.file("user_keys", package = "secret"), x) } alice_public <- keys("alice.pub") alice_private <- keys("alice.pem") bob_public <- keys("bob.pub") bob_private <- keys("bob.pem") carl_private <- keys("carl.pem") # Create vault vault <- file.path(tempdir(), ".vault") if (dir.exists(vault)) unlink(vault) # ensure vault is empty create_vault(vault) # Add users with their public keys add_user("alice", public_key = alice_public, vault = vault) add_user("bob", public_key = bob_public, vault = vault) list_users(vault = vault) # Share a secret secret <- list(username = "user123", password = "Secret123!") add_secret("secret", value = secret, users = c("alice", "bob"), vault = vault) list_secrets(vault = vault) # Alice and Bob can decrypt the secret with their private keys # Note that you would not normally have access to the private key # of any of your collaborators! get_secret("secret", key = alice_private, vault = vault) get_secret("secret", key = bob_private, vault = vault) # But Carl can't decrypt the secret try( get_secret("secret", key = carl_private, vault = vault) ) # Unshare the secret unshare_secret("secret", users = "bob", vault = vault) try( get_secret("secret", key = bob_private, vault = vault) ) # Delete the secret delete_secret("secret", vault = vault) list_secrets(vault) # Delete the users delete_user("alice", vault = vault) delete_user("bob", vault = vault) list_users(vault) ## End(Not run)
## Not run: # The `secret` package contains some user keys for demonstration purposes. # In this example, Alice shares a secret with Bob using a vault. keys <- function(x){ file.path(system.file("user_keys", package = "secret"), x) } alice_public <- keys("alice.pub") alice_private <- keys("alice.pem") bob_public <- keys("bob.pub") bob_private <- keys("bob.pem") carl_private <- keys("carl.pem") # Create vault vault <- file.path(tempdir(), ".vault") if (dir.exists(vault)) unlink(vault) # ensure vault is empty create_vault(vault) # Add users with their public keys add_user("alice", public_key = alice_public, vault = vault) add_user("bob", public_key = bob_public, vault = vault) list_users(vault = vault) # Share a secret secret <- list(username = "user123", password = "Secret123!") add_secret("secret", value = secret, users = c("alice", "bob"), vault = vault) list_secrets(vault = vault) # Alice and Bob can decrypt the secret with their private keys # Note that you would not normally have access to the private key # of any of your collaborators! get_secret("secret", key = alice_private, vault = vault) get_secret("secret", key = bob_private, vault = vault) # But Carl can't decrypt the secret try( get_secret("secret", key = carl_private, vault = vault) ) # Unshare the secret unshare_secret("secret", users = "bob", vault = vault) try( get_secret("secret", key = bob_private, vault = vault) ) # Delete the secret delete_secret("secret", vault = vault) list_secrets(vault) # Delete the users delete_user("alice", vault = vault) delete_user("bob", vault = vault) list_users(vault) ## End(Not run)
On Travis, every repo has a private/public key pair. This function adds a user and downloads the public key from Travis.
add_travis_user(travis_repo, email, vault = NULL)
add_travis_user(travis_repo, email, vault = NULL)
travis_repo |
Name of Travis repository, usually in a format
|
email |
Email address of the user. This is used to identify users. |
vault |
Vault location (starting point to find the vault).
To create a vault, use
If the starting point is a vault, that is used. Otherwise, if the
starting point is in a package tree, the |
Other user functions:
add_github_user()
,
add_user()
,
delete_user()
,
list_users()
## Not run: vault <- file.path(tempdir(), ".vault") create_vault(vault) add_travis_user("gaborcsardi/secret", vault = vault) list_users(vault = vault) delete_user("travis-gaborcsardi-secret", vault = vault) ## End(Not run)
## Not run: vault <- file.path(tempdir(), ".vault") create_vault(vault) add_travis_user("gaborcsardi/secret", vault = vault) list_users(vault = vault) delete_user("travis-gaborcsardi-secret", vault = vault) ## End(Not run)
By default the new user does not have access to any secrets.
See add_secret()
or share_secret()
to give them access.
add_user(email, public_key, vault = NULL)
add_user(email, public_key, vault = NULL)
email |
Email address of the user. This is used to identify users. |
public_key |
Public key of the user. This is used to encrypt the secrets for the different users. It can be
|
vault |
Vault location (starting point to find the vault).
To create a vault, use
If the starting point is a vault, that is used. Otherwise, if the
starting point is in a package tree, the |
Other user functions:
add_github_user()
,
add_travis_user()
,
delete_user()
,
list_users()
## Not run: # The `secret` package contains some user keys for demonstration purposes. # In this example, Alice shares a secret with Bob using a vault. keys <- function(x){ file.path(system.file("user_keys", package = "secret"), x) } alice_public <- keys("alice.pub") alice_private <- keys("alice.pem") bob_public <- keys("bob.pub") bob_private <- keys("bob.pem") carl_private <- keys("carl.pem") # Create vault vault <- file.path(tempdir(), ".vault") if (dir.exists(vault)) unlink(vault) # ensure vault is empty create_vault(vault) # Add users with their public keys add_user("alice", public_key = alice_public, vault = vault) add_user("bob", public_key = bob_public, vault = vault) list_users(vault = vault) # Share a secret secret <- list(username = "user123", password = "Secret123!") add_secret("secret", value = secret, users = c("alice", "bob"), vault = vault) list_secrets(vault = vault) # Alice and Bob can decrypt the secret with their private keys # Note that you would not normally have access to the private key # of any of your collaborators! get_secret("secret", key = alice_private, vault = vault) get_secret("secret", key = bob_private, vault = vault) # But Carl can't decrypt the secret try( get_secret("secret", key = carl_private, vault = vault) ) # Unshare the secret unshare_secret("secret", users = "bob", vault = vault) try( get_secret("secret", key = bob_private, vault = vault) ) # Delete the secret delete_secret("secret", vault = vault) list_secrets(vault) # Delete the users delete_user("alice", vault = vault) delete_user("bob", vault = vault) list_users(vault) ## End(Not run)
## Not run: # The `secret` package contains some user keys for demonstration purposes. # In this example, Alice shares a secret with Bob using a vault. keys <- function(x){ file.path(system.file("user_keys", package = "secret"), x) } alice_public <- keys("alice.pub") alice_private <- keys("alice.pem") bob_public <- keys("bob.pub") bob_private <- keys("bob.pem") carl_private <- keys("carl.pem") # Create vault vault <- file.path(tempdir(), ".vault") if (dir.exists(vault)) unlink(vault) # ensure vault is empty create_vault(vault) # Add users with their public keys add_user("alice", public_key = alice_public, vault = vault) add_user("bob", public_key = bob_public, vault = vault) list_users(vault = vault) # Share a secret secret <- list(username = "user123", password = "Secret123!") add_secret("secret", value = secret, users = c("alice", "bob"), vault = vault) list_secrets(vault = vault) # Alice and Bob can decrypt the secret with their private keys # Note that you would not normally have access to the private key # of any of your collaborators! get_secret("secret", key = alice_private, vault = vault) get_secret("secret", key = bob_private, vault = vault) # But Carl can't decrypt the secret try( get_secret("secret", key = carl_private, vault = vault) ) # Unshare the secret unshare_secret("secret", users = "bob", vault = vault) try( get_secret("secret", key = bob_private, vault = vault) ) # Delete the secret delete_secret("secret", vault = vault) list_secrets(vault) # Delete the users delete_user("alice", vault = vault) delete_user("bob", vault = vault) list_users(vault) ## End(Not run)
A vault is a folder that contains information about users and the secrets they share. You can create a vault as either a standalone folder, or as part of a package.
create_package_vault(path = ".") create_vault(path)
create_package_vault(path = ".") create_vault(path)
path |
Path to the R package. A file or directory within the package is fine, too. If the vault directory already exists, a message is given, and the function does nothing. |
A vault is a folder with a specific structure, containing two
directories: users
and secrets
.
In users
, each file contains a public key in PEM format. The name of
the file is the identifier of the key, an arbitrary name. We suggest
that you use email addresses to identify public keys. See also add_user()
.
In secrets
, each secret is stored in its own directory.
The directory of a secret contains
the secret, encrypted with its own AES key, and
the AES key, encrypted with the public keys of all users that have access to the secret, each in its own file.
To add a secret, see add_secret()
The directory of the vault, invisibly.
When you create a vault in a package, this vault is stored in the
inst/vault
directory of the package during development. At package
install time, this folder is copied to the vault
folder.
## Not run: # The `secret` package contains some user keys for demonstration purposes. # In this example, Alice shares a secret with Bob using a vault. keys <- function(x){ file.path(system.file("user_keys", package = "secret"), x) } alice_public <- keys("alice.pub") alice_private <- keys("alice.pem") bob_public <- keys("bob.pub") bob_private <- keys("bob.pem") carl_private <- keys("carl.pem") # Create vault vault <- file.path(tempdir(), ".vault") if (dir.exists(vault)) unlink(vault) # ensure vault is empty create_vault(vault) # Add users with their public keys add_user("alice", public_key = alice_public, vault = vault) add_user("bob", public_key = bob_public, vault = vault) list_users(vault = vault) # Share a secret secret <- list(username = "user123", password = "Secret123!") add_secret("secret", value = secret, users = c("alice", "bob"), vault = vault) list_secrets(vault = vault) # Alice and Bob can decrypt the secret with their private keys # Note that you would not normally have access to the private key # of any of your collaborators! get_secret("secret", key = alice_private, vault = vault) get_secret("secret", key = bob_private, vault = vault) # But Carl can't decrypt the secret try( get_secret("secret", key = carl_private, vault = vault) ) # Unshare the secret unshare_secret("secret", users = "bob", vault = vault) try( get_secret("secret", key = bob_private, vault = vault) ) # Delete the secret delete_secret("secret", vault = vault) list_secrets(vault) # Delete the users delete_user("alice", vault = vault) delete_user("bob", vault = vault) list_users(vault) ## End(Not run)
## Not run: # The `secret` package contains some user keys for demonstration purposes. # In this example, Alice shares a secret with Bob using a vault. keys <- function(x){ file.path(system.file("user_keys", package = "secret"), x) } alice_public <- keys("alice.pub") alice_private <- keys("alice.pem") bob_public <- keys("bob.pub") bob_private <- keys("bob.pem") carl_private <- keys("carl.pem") # Create vault vault <- file.path(tempdir(), ".vault") if (dir.exists(vault)) unlink(vault) # ensure vault is empty create_vault(vault) # Add users with their public keys add_user("alice", public_key = alice_public, vault = vault) add_user("bob", public_key = bob_public, vault = vault) list_users(vault = vault) # Share a secret secret <- list(username = "user123", password = "Secret123!") add_secret("secret", value = secret, users = c("alice", "bob"), vault = vault) list_secrets(vault = vault) # Alice and Bob can decrypt the secret with their private keys # Note that you would not normally have access to the private key # of any of your collaborators! get_secret("secret", key = alice_private, vault = vault) get_secret("secret", key = bob_private, vault = vault) # But Carl can't decrypt the secret try( get_secret("secret", key = carl_private, vault = vault) ) # Unshare the secret unshare_secret("secret", users = "bob", vault = vault) try( get_secret("secret", key = bob_private, vault = vault) ) # Delete the secret delete_secret("secret", vault = vault) list_secrets(vault) # Delete the users delete_user("alice", vault = vault) delete_user("bob", vault = vault) list_users(vault) ## End(Not run)
Remove a secret from the vault.
delete_secret(name, vault = NULL)
delete_secret(name, vault = NULL)
name |
Name of the secret to delete. |
vault |
Vault location (starting point to find the vault).
To create a vault, use
If the starting point is a vault, that is used. Otherwise, if the
starting point is in a package tree, the |
Other secret functions:
add_secret()
,
get_secret()
,
list_owners()
,
list_secrets()
,
local_key()
,
share_secret()
,
unshare_secret()
,
update_secret()
It also removes access of the user to all secrets, so if the user is re-added again, they will not have access to any secrets.
delete_user(email, vault = NULL)
delete_user(email, vault = NULL)
email |
Email address of the user. |
vault |
Vault location (starting point to find the vault).
To create a vault, use
If the starting point is a vault, that is used. Otherwise, if the
starting point is in a package tree, the |
Other user functions:
add_github_user()
,
add_travis_user()
,
add_user()
,
list_users()
Get the SSH public key of a GitHub user
get_github_key(github_user, i = 1)
get_github_key(github_user, i = 1)
github_user |
GitHub username. |
i |
Which key to get, in case the user has multiple keys.
|
Character scalar.
Retrieve a secret from the vault.
get_secret(name, key = local_key(), vault = NULL)
get_secret(name, key = local_key(), vault = NULL)
name |
Name of the secret. |
key |
The private RSA key to use. It defaults to the current user's default key. |
vault |
Vault location (starting point to find the vault).
To create a vault, use
If the starting point is a vault, that is used. Otherwise, if the
starting point is in a package tree, the |
Other secret functions:
add_secret()
,
delete_secret()
,
list_owners()
,
list_secrets()
,
local_key()
,
share_secret()
,
unshare_secret()
,
update_secret()
## Not run: # The `secret` package contains some user keys for demonstration purposes. # In this example, Alice shares a secret with Bob using a vault. keys <- function(x){ file.path(system.file("user_keys", package = "secret"), x) } alice_public <- keys("alice.pub") alice_private <- keys("alice.pem") bob_public <- keys("bob.pub") bob_private <- keys("bob.pem") carl_private <- keys("carl.pem") # Create vault vault <- file.path(tempdir(), ".vault") if (dir.exists(vault)) unlink(vault) # ensure vault is empty create_vault(vault) # Add users with their public keys add_user("alice", public_key = alice_public, vault = vault) add_user("bob", public_key = bob_public, vault = vault) list_users(vault = vault) # Share a secret secret <- list(username = "user123", password = "Secret123!") add_secret("secret", value = secret, users = c("alice", "bob"), vault = vault) list_secrets(vault = vault) # Alice and Bob can decrypt the secret with their private keys # Note that you would not normally have access to the private key # of any of your collaborators! get_secret("secret", key = alice_private, vault = vault) get_secret("secret", key = bob_private, vault = vault) # But Carl can't decrypt the secret try( get_secret("secret", key = carl_private, vault = vault) ) # Unshare the secret unshare_secret("secret", users = "bob", vault = vault) try( get_secret("secret", key = bob_private, vault = vault) ) # Delete the secret delete_secret("secret", vault = vault) list_secrets(vault) # Delete the users delete_user("alice", vault = vault) delete_user("bob", vault = vault) list_users(vault) ## End(Not run)
## Not run: # The `secret` package contains some user keys for demonstration purposes. # In this example, Alice shares a secret with Bob using a vault. keys <- function(x){ file.path(system.file("user_keys", package = "secret"), x) } alice_public <- keys("alice.pub") alice_private <- keys("alice.pem") bob_public <- keys("bob.pub") bob_private <- keys("bob.pem") carl_private <- keys("carl.pem") # Create vault vault <- file.path(tempdir(), ".vault") if (dir.exists(vault)) unlink(vault) # ensure vault is empty create_vault(vault) # Add users with their public keys add_user("alice", public_key = alice_public, vault = vault) add_user("bob", public_key = bob_public, vault = vault) list_users(vault = vault) # Share a secret secret <- list(username = "user123", password = "Secret123!") add_secret("secret", value = secret, users = c("alice", "bob"), vault = vault) list_secrets(vault = vault) # Alice and Bob can decrypt the secret with their private keys # Note that you would not normally have access to the private key # of any of your collaborators! get_secret("secret", key = alice_private, vault = vault) get_secret("secret", key = bob_private, vault = vault) # But Carl can't decrypt the secret try( get_secret("secret", key = carl_private, vault = vault) ) # Unshare the secret unshare_secret("secret", users = "bob", vault = vault) try( get_secret("secret", key = bob_private, vault = vault) ) # Delete the secret delete_secret("secret", vault = vault) list_secrets(vault) # Delete the users delete_user("alice", vault = vault) delete_user("bob", vault = vault) list_users(vault) ## End(Not run)
Retrieve the public key of a Travis CI repository
get_travis_key(travis_repo)
get_travis_key(travis_repo)
travis_repo |
The repository slug, e.g. |
Character scalar, the key. If the repository does not exist, or it is not user in Travis CI, an HTTP 404 error is thrown.
List users that have access to a secret
list_owners(name, vault = NULL)
list_owners(name, vault = NULL)
name |
Name of the secret, a string that can contain alphanumeric characters, underscores, dashes and dots. |
vault |
Vault location (starting point to find the vault).
To create a vault, use
If the starting point is a vault, that is used. Otherwise, if the
starting point is in a package tree, the |
Other secret functions:
add_secret()
,
delete_secret()
,
get_secret()
,
list_secrets()
,
local_key()
,
share_secret()
,
unshare_secret()
,
update_secret()
Returns a data frame with secrets and emails that these are shared with.
The emails are in a list-column, each element of the email
column is
a character vector.
list_secrets(vault = NULL)
list_secrets(vault = NULL)
vault |
Vault location (starting point to find the vault).
To create a vault, use
If the starting point is a vault, that is used. Otherwise, if the
starting point is in a package tree, the |
data.frame
Other secret functions:
add_secret()
,
delete_secret()
,
get_secret()
,
list_owners()
,
local_key()
,
share_secret()
,
unshare_secret()
,
update_secret()
List users
list_users(vault = NULL)
list_users(vault = NULL)
vault |
Vault location (starting point to find the vault).
To create a vault, use
If the starting point is a vault, that is used. Otherwise, if the
starting point is in a package tree, the |
Other user functions:
add_github_user()
,
add_travis_user()
,
add_user()
,
delete_user()
Reads a local secret key from disk. The location of this file can be
specified in the USER_KEY
environment variable.
If this environment variable does not exist, then attempts to read the
key from:
~/.ssh/id_rsa
, and
~/.ssh/id_rsa.pem
.
local_key()
local_key()
The location of the key is defined by:
Sys.getenv("USER_KEY")
To use a local in a different location, set an environment variable:
Sys.setenv(USER_KEY = "path/to/private/key")
Other secret functions:
add_secret()
,
delete_secret()
,
get_secret()
,
list_owners()
,
list_secrets()
,
share_secret()
,
unshare_secret()
,
update_secret()
Update a secret in the vault.
update_secret(name, value, key = local_key(), vault = NULL)
update_secret(name, value, key = local_key(), vault = NULL)
name |
Name of the secret. |
value |
Value of the secret, an arbitrary R object that
will be serialized using |
key |
The private RSA key to use. It defaults to the current user's default key. |
vault |
Vault location (starting point to find the vault).
To create a vault, use
If the starting point is a vault, that is used. Otherwise, if the
starting point is in a package tree, the |
Other secret functions:
add_secret()
,
delete_secret()
,
get_secret()
,
list_owners()
,
list_secrets()
,
local_key()
,
share_secret()
,
unshare_secret()