Implementation Mechanisms

This reference guide provides comprehensive technical information about the implementation mechanisms available for configuring data access in Posit Connect. It is designed as supporting documentation for the Data Access Management lesson and serves as a detailed technical reference for system administrators who need to configure data access strategies.

NoteAbout This Reference

This document is reference material rather than a standalone lesson. For learning objectives, hands-on activities, and knowledge checks, please refer to the main Data Access Management lesson.

Implementation mechanisms are the technical tools and configuration methods you use to enable content to access data securely. The appropriate mechanism depends on your data source type, authentication strategy, and security requirements. The implementation mechanisms described in this guide help prevent hard-coding credentials within applications.

Overview

This guide covers the following implementation mechanisms:

  • Environment variables: Content-level and server-wide configuration
  • Service account users: Linux user management for process isolation
  • Current user execution: Interactive content running as viewer’s identity
  • Decision frameworks: Guidance for selecting the appropriate mechanism
NoteUnderstanding “Service Account” Terminology

This document uses “service account” in two distinct contexts:

  1. Database service account: A shared database user whose credentials are used by content to connect to databases (covered in the Database Connections reference)
  2. Linux service account user: A dedicated Linux user on the Connect server that runs specific content (covered in this document)

These can work together: content running as a Linux service account user can use database service account credentials stored in DSNs or environment variables.

Environment Variables

Environment variables provide a way to store configuration and secrets outside of application code. They can be configured using different scopes in Posit Connect: at the content-level or server-wide.

Content-level Environment Variables

Content-level environment variables are scoped to a specific content item and are only accessible to that content. The values are encrypted at rest in Connect’s database and decrypted only when injected into the application’s runtime environment.

These content-level environment variables are useful to store sensitive values that are specific to one application or content item such as API keys, database credentials, or configuration values that should not be hard-coded.

These variables can be set via Connect’s web interface or its API:

  • Setting via Connect UI:

    1. Navigate to content settings
    2. Go to “Vars” tab
    3. Add key-value pairs
  • Setting via Connect API:

    # Replace '{guid}' with your content's GUID (found in the content URL or via API) and make sure that you set the `CONNECT_API_KEY` environment variable. 
    
    # List environment variables
    curl -X GET \
      "https://connect.example.com/__api__/v1/content/{guid}/environment" \
      -H "Authorization: Key ${CONNECT_API_KEY}"
    
    # Set environment variable
    curl -X PATCH \
      "https://connect.example.com/__api__/v1/content/{guid}/environment" \
      -H "Authorization: Key ${CONNECT_API_KEY}" \
      -H "Content-Type: application/json" \
      -d '[{"name": "DATABASE_URL", "value": "postgresql://..."}]'

When using these environment variables, you can rely on R or Python’s function to bring their values into the scripts:

# Read environment variable
db_url <- Sys.getenv("DATABASE_URL")

# Use in connection
con <- dbConnect(
  odbc::odbc(),
  .connection_string = db_url
)
import os

# Read environment variable
db_url = os.environ.get("DATABASE_URL")

# Use in connection
conn = pyodbc.connect(db_url)

Server-wide Environment Variables

Server-wide environment variables are configured using a supervisor script. Supervisors are programs or scripts executed before launching content processes, allowing you to set global environment variables, perform initialization tasks, or configure the runtime environment.

This approach is useful for:

  • Shared configuration across all applications (e.g., proxy settings, default API endpoints)
  • Server-level secrets that all content should have access to
  • Default values that all content should inherit
  • Environment-specific settings (development, staging, production)

An example supervisor script for setting global environment variables is included in the Connect Admin Guide.

Using these variables in code is the same as content-level variables (via Sys.getenv() in R or os.environ in Python). Content-level environment variables take precedence over server-wide variables if both define the same variable name.

Service Account Users

Service accounts are Linux users created specifically to run content with specific permissions and access rights. These accounts do not need to be associated with user accounts. Typically, there are only a few service account users that are meant to execute non-interactive content (e.g., scheduled reports).

By default, all content on Connect runs as the rstudio-connect user. This user has minimal permissions for security.

Creating additional service accounts can be helpful when you need to:

  • Isolate permissions between different content items
  • Provide specific file system access
  • Use user-level DSNs with different credentials
  • Implement principle of least privilege

Creating Service Account Users

To create a Linux service account user for running content, you need to create a Linux user on the Connect server which is a member of the primary group of the default run-as user (default group: rstudio-connect but configurable via Applications.SharedRunAsUnixGroup).

Configuring Content to Use Service Accounts

Administrators and Publishers (if allowed by Connect’s configuration setting: Authorization.PublishersCanManageRunAs) can choose the service account that will run the content from the web interface:

  1. Navigate to content settings
  2. Go to “Access” tab
  3. Under “Who runs this content on the server”
  4. Select the service account user

Administrators can also update the user running content via the API:

# Replace {guid} with your content's GUID
curl -X PATCH \
  "https://connect.example.com/__api__/v1/content/{guid}" \
  -H "Authorization: Key ${CONNECT_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{"run_as": "service_account_name"}'

User-level DSNs for Service Accounts

Service accounts can have their own DSN configurations in their home directory by editing ~/.odbc.ini (note the dot prefix for user-level configuration). This allows each service account to use different database credentials while sharing the same driver configuration.

For detailed information on configuring DSNs, see the Database Connections reference.

File System Access

Service accounts can be granted specific file system permissions. This approach is useful in regulated industries where data governance is critical and needs to be enforced at multiple layers. Setting restrictive file system permissions enforces the principle of least privilege at the OS level.

# Create a data directory
sudo mkdir -p /data/service_data

# Set ownership
sudo chown service_account_name:rstudio-connect /data/service_data

# Set permissions (adjust based on the security policies at your organization)
sudo chmod 750 /data/service_data

Current User Execution

Current user execution allows interactive content to run as the Linux user account of the viewer accessing the content, rather than as a shared service account. This provides better process isolation and enforces file permissions based on each viewer’s identity.

Prerequisites and Limitations

Supported content types: - Interactive content only: Shiny, Dash, Gradio, Bokeh, Streamlit - Not supported for scheduled reports or APIs

Limitations: - Not supported when using off-host execution (e.g., Kubernetes launchers) - Requires Linux user accounts for all viewers - All Linux users must belong to the group defined in Applications.SharedRunAsUnixGroup (default: rstudio-connect)

Configuration Approach

With recent versions of Posit Connect, we recommend using the Connect Nameservice to automatically map Connect users to Linux users. This eliminates the need for manual PAM configuration.

For detailed configuration instructions, see: - Current User Execution in the Connect Admin Guide - Nameservice configuration for automatic user mapping

Summary and Decision Guide

Start with the simplest approach that meets your requirements:

  1. For database connections: Use DSNs with database service account credentials (see Database Connections reference)
    • Centralizes database configuration
    • Supports both R and Python
    • Credentials managed by admins, not developers
  2. For API keys and secrets: Use content-level environment variables
    • Encrypted at rest
    • Scoped to specific content
    • Easy to rotate without code changes
    • Credentials can be managed directly by developers
  3. For shared configuration: Use server-wide environment variables via supervisor scripts
    • Available to all content
    • Reduces duplication
    • Good for environment-specific settings
  4. For permission isolation: Use Linux service account users
    • Isolate file system access
    • Separate credentials per service account
    • Enforce least privilege at OS level
  5. For user-specific access: Use current user execution
    • Interactive content only
    • Per-user file permissions
    • Process isolation per viewer

For a more detailed decision framework that considers authentication patterns and data source types, see the Data Access Management lesson.