Skip to content

Configuration

packageR reads server options from command-line flags, PACKAGE_R_ environment variables, or its configuration file. Application settings are stored in the packageR database and managed with package-r config. Object-storage credentials belong to the process and are not stored in the database or user records.

Runtime state

packageR is stateless. Object data stays in object storage. The local Bolt database is a runtime cache for settings, user records, and public shares. It is not the source of the stored data.

For hosted deployments, use a separate process to prepare the database before packageR starts. The database does not need a backup or a persistent volume. The Kubernetes guide shows an init container and an emptyDir volume.

Defaults

packageR listens on 127.0.0.1:8888 and uses /tmp/package-r.db by default. Create the database and its first user before you start the server. JSON username/password authentication is the default.

Variable Default Description
PACKAGE_R_DATABASE /tmp/package-r.db Bolt runtime-cache path.
PACKAGE_R_ADDRESS 127.0.0.1 Listen address.
PACKAGE_R_PORT 8888 HTTP port.
PACKAGE_R_LOG stdout Log output.
PACKAGE_R_LOG_LEVEL NOTICE packageR and rclone log level: ERROR, NOTICE, INFO, or DEBUG.
PACKAGE_R_BASEURL Empty URL path prefix.
PACKAGE_R_TOKEN_EXPIRATION_TIME 2h User session lifetime.
PACKAGE_R_CORS_ALLOWED_ORIGINS Empty Comma-separated browser origins allowed to make cross-origin requests. Use * to allow every origin.

Cross-origin access is disabled by default. Origins must include the scheme and, when applicable, the port. For example:

PACKAGE_R_CORS_ALLOWED_ORIGINS=https://viewer.example.org,https://portal.example.org

packageR handles browser preflight requests and allows the methods and headers used by its API. It does not enable credentialed cookie requests. Configure CORS separately on object storage when browsers open presigned URLs directly.

With empty AWS values, packageR uses the ambient AWS credential chain and AWS S3. Storage requests fail if that chain does not provide usable credentials.

Object storage

These values configure rclone VFS and presigned links.

Variable Default Required Description
AWS_ACCESS_KEY_ID Empty With static credentials S3 access key. Set it with AWS_SECRET_ACCESS_KEY.
AWS_SECRET_ACCESS_KEY Empty With static credentials S3 secret key. Set it with AWS_ACCESS_KEY_ID.
AWS_SESSION_TOKEN Empty For temporary static keys Optional session token.
AWS_ROLE_ARN Empty Injected for web identity Role used by workload identity, including AWS IRSA.
AWS_WEB_IDENTITY_TOKEN_FILE Empty Injected for web identity Path to the projected workload token.
AWS_ROLE_SESSION_NAME Empty No Optional web-identity role session name.
PACKAGE_R_ROOT / No S3 service root, or one bucket name.
PACKAGE_R_BUCKETS Empty No Comma-separated bucket catalog for the S3 service root.
AWS_ENDPOINT_URL Empty For custom endpoints S3-compatible API endpoint. An empty value selects AWS S3.
AWS_REGION Empty Service dependent S3 region. The credential provider can supply it.
XDG_CACHE_HOME Platform user cache directory No Parent directory for the rclone VFS and DuckDB caches.

Choose one credential mode:

  • For workload identity, leave AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY unset. rclone uses its S3 credential chain. This can use AWS IRSA, a container identity, an instance identity, or a shared credential file.
  • For static credentials, set both key variables. Set AWS_SESSION_TOKEN for temporary credentials. Static credentials take priority.

Startup fails when only one static key variable is set. Do not put projected tokens or static credentials in packageR configuration, logs, or the Bolt database.

The service keeps process-owned rclone VFS instances. An explicit bucket catalog uses one instance for each configured bucket. User settings cannot change the endpoint, credentials, root, or bucket catalog. The credential provider refreshes temporary credentials when the selected identity method supports refresh.

Directory listings use the server modification time returned by S3. This avoids a separate metadata request for each listed object.

Chunked and seek-based uploads use the rclone VFS write cache. Set XDG_CACHE_HOME to choose its parent directory. For example, XDG_CACHE_HOME=/var/cache/package-r places the VFS cache below /var/cache/package-r/rclone. If the variable is unset on Linux, the default is $HOME/.cache/rclone. The directory must be writable and have enough free space. Storage initialization fails if it is not available.

DuckDB uses the same cache root. With the example above, its httpfs extension is stored under /var/cache/package-r/package-r/duckdb-extensions. The first catalog query downloads the extension if it is not cached. A writable temporary volume is sufficient. A persistent volume avoids downloading it again after each restart. Catalog storage must support ranged GET requests and may receive HEAD requests.

With PACKAGE_R_ROOT=/ and an empty PACKAGE_R_BUCKETS, the top-level entries come from S3 bucket discovery. The credentials need permission to list buckets. On AWS, this is s3:ListAllMyBuckets.

Set PACKAGE_R_BUCKETS when the identity can use known buckets but cannot list all buckets:

PACKAGE_R_ROOT=/
PACKAGE_R_BUCKETS=data,archive

packageR then creates the top-level listing from this catalog and does not use S3 bucket discovery. Opening and listing a configured bucket still needs its bucket-list permission, such as AWS s3:ListBucket. Object actions need the matching provider permissions. Bucket names must be unique. packageR rejects a rename between buckets because each bucket has a separate backend.

With PACKAGE_R_ROOT=my-bucket, / in packageR is the root of my-bucket. packageR does not need permission to list all buckets. It still needs s3:ListBucket and the required object permissions for my-bucket. Leave PACKAGE_R_BUCKETS empty in this mode. packageR rejects a bucket catalog with a direct bucket root because other catalog entries would not be reachable.

Browser COG previews use presigned object URLs. Configure S3 CORS for the packageR and viewer origins. Allow GET, HEAD, and the Range request header. Expose Accept-Ranges, Content-Range, Content-Length, and ETag. Storage proxies must preserve range requests and 206 responses.

Authentication and authorization

packageR uses JSON username/password authentication by default. It does not create a default account. Configure authentication when you prepare the database. The main process reads the result from that database.

Username and password

This is the packageR default. Create users with package-r users add. The web interface and HTTP API do not manage user records.

Trusted identity header

Use a header that contains the username. Include these options in the package-r config init command:

./package-r config init \
  --auth.method=proxy \
  --auth.header=X-Username \
  --auth.mapper=

packageR trusts the complete header value. The upstream proxy must authenticate the request and replace any client-supplied X-Username header.

Validated JWT

Use Authorization: Bearer <token>, a JWKS URL, and the claim that identifies the user:

./package-r config init \
  --auth.method=proxy \
  --auth.header=Authorization \
  --auth.mapper=.sub \
  --auth.jwt.jwks-url=https://identity.example/.well-known/jwks.json \
  --auth.jwt.issuer=https://identity.example/ \
  --auth.jwt.audience=package-r

The mapper selects the packageR username. It does not limit token validation. Use .sub unless the identity provider defines another stable, unique claim.

If claim mapping is set without a JWKS URL, packageR logs a warning and only decodes the token. This is allowed for a trusted upstream proxy.

On-demand users

Add --signup=true to the configuration command to enable on-demand user creation for proxy authentication. The first request from a valid new identity then creates a user. Add --create-user-dir=true to create /home/<username> and hide sibling home directories.

New users have these defaults:

Setting Default
Scope /
Browse names and directories Allowed within the scope and path rules
Create, rename, modify, delete Denied

Default permissions apply only to new users. Existing users keep their stored permissions.

User-directory mode does not limit the user to their home directory. The default scope remains /. It hides other home directories and protects /home from recursive changes. Set an explicit user scope or additional rules to restrict access outside the user's home.

User-directory mode requires one bucket in PACKAGE_R_ROOT. packageR refuses to start when user-directory mode is enabled and PACKAGE_R_ROOT=/.

How access is calculated

packageR applies these access controls in order:

  1. The S3 credentials and their storage policy define the maximum access.
  2. PACKAGE_R_ROOT selects the service root or one direct bucket.
  3. PACKAGE_R_BUCKETS can replace service-root discovery with an explicit bucket catalog.
  4. The user scope selects a subtree below that root. Paths cannot escape it.
  5. Hidden-file handling, global rules, and user rules filter normalized paths. Matching rules are evaluated in order, and the last matching rule wins.
  6. User-directory mode denies sibling homes and protects their shared parent from recursive changes. This boundary cannot be overridden by a user rule.
  7. User permission flags control actions such as create, rename, modify, and delete.

Catalogs

Set a catalog name on each share with package-r shares add --catalog-name. Use --asset-mappings on the same command if that share needs URL-to-path mappings. Without --catalog-name, the share has no catalog.

Set the optional STAC Browser URL when you prepare the database:

./package-r config set \
  --stac-browser-url=http://localhost:8080/external/

The default is empty. packageR does not add a STAC Browser link unless you set this option.

Catalog names and mapping targets must stay inside the shared path. Absolute names and parent-path escapes are invalid. Most catalogs do not need asset mappings.

See the HTTP API for route behavior.