diff --git a/R/dialogs.R b/R/dialogs.R
index deaf4fb..89ca224 100644
--- a/R/dialogs.R
+++ b/R/dialogs.R
@@ -73,35 +73,3 @@ showPrompt <- function(title, message, default = NULL) {
 showQuestion <- function(title, message, ok = NULL, cancel = NULL) {
   callFun("showQuestion", title, message, ok, cancel)
 }
-
-
-
-#' Prompt user for secret
-#'
-#' Request a secret from the user. If the `keyring` package is installed, it
-#' will be used to cache requested secrets.
-#' 
-#' 
-#' @param name The name of the secret.
-#' 
-#' @param message A character vector with the contents to display in the main
-#'   dialog area.
-#'   
-#' @param title The title to display in the dialog box.
-#' 
-#' @note The \code{askForSecret} function was added in version 1.1.419 of
-#'   RStudio.
-#' 
-#' @export
-askForSecret <- function(
-  name,
-  message = paste(name, ":", sep = ""),
-  title = paste(name, "Secret")) {
-
-  if (hasFun("askForSecret") || isChildProcess()) {
-    callFun("askForSecret", name, title, message)
-  } else {
-    askForPassword(message)
-  }
-
-}
diff --git a/R/secrets.R b/R/secrets.R
new file mode 100644
index 0000000..669e5aa
--- /dev/null
+++ b/R/secrets.R
@@ -0,0 +1,121 @@
+
+# returns the secret associated with a key 'key', or NULL
+# if no secret is available
+retrieveSecret <- function(tag, label) {
+  
+  # nothing to do if we don't have a key
+  if (is.null(tag))
+    return(NULL)
+  
+  # build full name of environment variable
+  name <- paste("RSTUDIOAPI_SECRET", toupper(tag), sep = "_")
+  
+  # check for a definition
+  value <- Sys.getenv(name, unset = NA)
+  if (!is.na(value))
+    return(value)
+  
+  # for non-interactive sessions, give a warning; otherwise,
+  # fall through an attempt to ask for a password
+  if (!interactive() && !isChildProcess()) {
+    fmt <- "The %s associated with tag '%s' is not set or could not be retrieved."
+    msg <- sprintf(fmt, label, tag)
+    warning(msg)
+  }
+  
+}
+
+#' @param name The name to associate with the secret. This name will be used
+#'   to locate the requested secret; e.g. when requested via the `keyring`
+#'   package.
+#'   
+#' @param prompt The prompt to be shown to the user.
+#' 
+#' @param tag An optional tag, used to assist `rstudioapi` in reading secrets
+#'   in non-interactive \R sessions. Currently, when provided, `rstudioapi`
+#'   will check if an environment variable of the name `RSTUDIOAPI_SECRET_<KEY>`
+#'   is defined; if so, that environment variable will be used to supply the
+#'   password. If the variable is unset, then (in interactive sessions) the user
+#'   will be prompted for a password; otherwise, a warning will be shown.
+#'
+#' @name dialog-params
+NULL
+
+#' Ask the user for a password interactively
+#' 
+#' Ask the user for a password interactively. A dialog requesting a password
+#' from the user will be shown, and the value of the retrieved password will
+#' be returned.
+#' 
+#' RStudio also sets the global \code{askpass} option to the
+#' [askForPassword()] function so that it can be invoked in a
+#' front-end independent manner.
+#' 
+#' @inheritParams dialog-params
+#' 
+#' @note The \code{askForPassword} function was added in version 0.99.853 of
+#'   RStudio.
+#' 
+#' @examples
+#' 
+#' \dontrun{
+#' rstudioapi::askForPassword("Please enter your password:")
+#' }
+#' 
+#' @export askForPassword
+askForPassword <- function(prompt = "Please enter your password:",
+                           name = NULL,
+                           tag = NULL)
+{
+  # if 'name' was supplied, delegate to askForSecret
+  if (!is.null(name))
+    return(askForSecret(name = name, message = prompt, tag = tag))
+  
+  # try to retrieve password non-interactively
+  password <- retrieveSecret(tag, "password")
+  if (!is.null(password))
+    return(password)
+  
+  # request password from user
+  callFun("askForPassword", prompt)
+}
+
+#' Prompt user for secret
+#'
+#' Request a secret from the user. If the `keyring` package is installed, it
+#' will be used to cache requested secrets.
+#' 
+#' @inheritParams dialog-params
+#' 
+#' @param message A character vector with the contents to display in the main
+#'   dialog area.
+#'   
+#' @param title The title to display in the dialog box.
+#' 
+#' @note The \code{askForSecret} function was added in version 1.1.419 of
+#'   RStudio.
+#' 
+#' @export
+askForSecret <- function(name,
+                         message = NULL,
+                         title = "Secret",
+                         tag = NULL)
+{
+  # resolve 'message' argument
+  if (is.null(message)) {
+    fmt <- "Please enter a secret to associate with name '%s':"
+    message <- sprintf(fmt, name)
+  }
+  
+  # try to retrieve secret non-interactively
+  secret <- retrieveSecret(tag, "secret")
+  if (!is.null(secret))
+    return(secret)
+  
+  # use 'askForSecret' if available
+  if (hasFun("askForSecret") || isChildProcess())
+    return(callFun("askForSecret", name, title, message))
+  
+  # otherwise, fall back to askForPassword
+  askForPassword(message)
+}
diff --git a/R/stubs.R b/R/stubs.R
index 4eb717a..cc7fc55 100644
--- a/R/stubs.R
+++ b/R/stubs.R
@@ -249,32 +249,6 @@ navigateToFile <- function(file = character(0),
 }
 
 
-#' Ask the user for a password interactively
-#' 
-#' Ask the user for a password interactively.
-#' 
-#' RStudio also sets the global \code{askpass} option to the
-#' \code{rstudioapi::askForPassword} function so that it can be invoked in a
-#' front-end independent manner.
-#' 
-#' @param prompt The prompt to be shown to the user.
-#' 
-#' @note The \code{askForPassword} function was added in version 0.99.853 of
-#'   RStudio.
-#' 
-#' @examples
-#' 
-#' \dontrun{
-#' rstudioapi::askForPassword("Please enter your password")
-#' }
-#' 
-#' @export askForPassword
-askForPassword <- function(prompt = "Please enter your password") {
-  callFun("askForPassword", prompt)
-}
-
-
-
 #' Retrieve path to active RStudio project
 #' 
 #' Get the path to the active RStudio project (if any). If the path contains
diff --git a/man/askForPassword.Rd b/man/askForPassword.Rd
index dc280ef..05c431e 100644
--- a/man/askForPassword.Rd
+++ b/man/askForPassword.Rd
@@ -1,20 +1,33 @@
 % Generated by roxygen2: do not edit by hand
-% Please edit documentation in R/stubs.R
+% Please edit documentation in R/secrets.R
 \name{askForPassword}
 \alias{askForPassword}
 \title{Ask the user for a password interactively}
 \usage{
-askForPassword(prompt = "Please enter your password")
+askForPassword(prompt = "Please enter your password:", name = NULL, tag = NULL)
 }
 \arguments{
 \item{prompt}{The prompt to be shown to the user.}
+
+\item{name}{The name to associate with the secret. This name will be used
+to locate the requested secret; e.g. when requested via the \code{keyring}
+package.}
+
+\item{tag}{An optional tag, used to assist \code{rstudioapi} in reading secrets
+in non-interactive \R sessions. Currently, when provided, \code{rstudioapi}
+will check if an environment variable of the name \verb{RSTUDIOAPI_SECRET_<KEY>}
+is defined; if so, that environment variable will be used to supply the
+password. If the variable is unset, then (in interactive sessions) the user
+will be prompted for a password; otherwise, a warning will be shown.}
 }
 \description{
-Ask the user for a password interactively.
+Ask the user for a password interactively. A dialog requesting a password
+from the user will be shown, and the value of the retrieved password will
+be returned.
 }
 \details{
 RStudio also sets the global \code{askpass} option to the
-\code{rstudioapi::askForPassword} function so that it can be invoked in a
+\code{\link[=askForPassword]{askForPassword()}} function so that it can be invoked in a
 front-end independent manner.
 }
 \note{
@@ -24,7 +37,7 @@ RStudio.
 \examples{
 
 \dontrun{
-rstudioapi::askForPassword("Please enter your password")
+rstudioapi::askForPassword("Please enter your password:")
 }
 
 }
diff --git a/man/askForSecret.Rd b/man/askForSecret.Rd
index bf5dde8..a0cc0c6 100644
--- a/man/askForSecret.Rd
+++ b/man/askForSecret.Rd
@@ -1,22 +1,27 @@
 % Generated by roxygen2: do not edit by hand
-% Please edit documentation in R/dialogs.R
+% Please edit documentation in R/secrets.R
 \name{askForSecret}
 \alias{askForSecret}
 \title{Prompt user for secret}
 \usage{
-askForSecret(
-  name,
-  message = paste(name, ":", sep = ""),
-  title = paste(name, "Secret")
-)
+askForSecret(name, message = NULL, title = "Secret", tag = NULL)
 }
 \arguments{
-\item{name}{The name of the secret.}
+\item{name}{The name to associate with the secret. This name will be used
+to locate the requested secret; e.g. when requested via the \code{keyring}
+package.}
 
 \item{message}{A character vector with the contents to display in the main
 dialog area.}
 
 \item{title}{The title to display in the dialog box.}
+
+\item{tag}{An optional tag, used to assist \code{rstudioapi} in reading secrets
+in non-interactive \R sessions. Currently, when provided, \code{rstudioapi}
+will check if an environment variable of the name \verb{RSTUDIOAPI_SECRET_<KEY>}
+is defined; if so, that environment variable will be used to supply the
+password. If the variable is unset, then (in interactive sessions) the user
+will be prompted for a password; otherwise, a warning will be shown.}
 }
 \description{
 Request a secret from the user. If the \code{keyring} package is installed, it