This is an automated email from the ASF dual-hosted git repository.

erickguan pushed a commit to branch threat-model
in repository https://gitbox.apache.org/repos/asf/opendal-oli.git

commit 203649557c35e2d5822f7ffe9a212ec3926a41a7
Author: Erick Guan <[email protected]>
AuthorDate: Tue Jul 7 22:23:33 2026 +0800

    doc: add threat model
---
 AGENTS.md       |  11 ++
 SECURITY.md     |  64 ++++++++++
 THREAT_MODEL.md | 383 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 458 insertions(+)

diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 0000000..b37b8fa
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,11 @@
+# AGENTS.md
+
+Guidance for AI coding agents working in this repository.
+
+## Security
+
+Security model: [SECURITY.md](./SECURITY.md)
+
+Agents that scan this repository should consult `SECURITY.md` and the threat
+model it links (`THREAT_MODEL.md`) for the project's in-scope / out-of-scope
+declarations, adversary model, and known non-findings before reporting issues.
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 0000000..3ea313d
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,64 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+
+# Security Policy
+
+## Reporting a Vulnerability
+
+Apache OpenDAL Oli follows the
+[Apache Software Foundation security 
process](https://www.apache.org/security/).
+
+Please report suspected vulnerabilities privately to `[email protected]` or
+`[email protected]` before public disclosure. Do not open public 
GitHub
+issues or pull requests for security reports.
+
+Please include:
+
+- the project name, `Apache OpenDAL Oli`;
+- affected version, commit, platform, and installation method;
+- the command, profile shape, service type, and signing mode involved;
+- whether credentials, signed requests, local files, object data, or metadata
+  can be exposed or modified;
+- a minimal reproducer and any relevant logs with secrets redacted.
+
+## Supported Use
+
+`oli` is a local command-line client for OpenDAL-backed storage. It runs with
+the authority of the local user account and the credentials configured in its
+profile, environment, ambient credential chain, or custom signing setup. For
+services that require request signing, signing and credential lookup are
+delegated to OpenDAL and its signing integrations.
+
+Users should:
+
+- protect `~/.config/oli/config.toml` and equivalent platform config files as
+  secret material when they contain credentials;
+- protect environment variables named like `OLI_PROFILE_<PROFILE>_<OPTION>`;
+- verify storage endpoints before using profiles that sign requests;
+- avoid placing long-lived credentials in shell history, terminal transcripts,
+  CI logs, or shared config files;
+- treat `oli config view`, command output, object paths, metadata, benchmark
+  reports, and error messages as potentially sensitive local output;
+- use least-privilege storage credentials and service-side access controls.
+
+## Threat Model
+
+The security boundary, signing assumptions, in-scope issues, out-of-scope
+deployment responsibilities, and triage guidance are documented in
+[THREAT_MODEL.md](./THREAT_MODEL.md).
diff --git a/THREAT_MODEL.md b/THREAT_MODEL.md
new file mode 100644
index 0000000..89e7c0d
--- /dev/null
+++ b/THREAT_MODEL.md
@@ -0,0 +1,383 @@
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+
+# Apache OpenDAL Oli Threat Model
+
+## 1. Status
+
+This document defines the security boundary for Apache OpenDAL Oli (`oli`), a
+local command-line interface for manipulating data through Apache OpenDAL
+profiles. Use it to decide whether a report belongs to `oli`, OpenDAL or a
+signing component, a storage backend, or the user's deployment.
+
+The canonical disclosure process is in [SECURITY.md](./SECURITY.md). Reports
+that may affect security should be reported privately before public disclosure.
+
+## 2. Purpose
+
+`oli` is a local CLI. It parses command-line arguments, loads storage profiles,
+constructs OpenDAL `Operator` instances, and runs file-like operations such as
+`ls`, `cat`, `cp`, `mv`, `rm`, `tee`, `edit`, `stat`, and `bench`.
+
+The most security-sensitive path is request signing. `oli` does not implement a
+general key-management system itself; it passes profile options and operation
+inputs into OpenDAL, which may use service-specific signing integrations and
+custom key providers to sign requests.
+
+`oli` is not a daemon, gateway, identity provider, authorization service,
+sandbox, key-management service, policy engine, malware scanner, or
+multi-tenant broker. It does not decide whether a human, script, tenant, or CI
+job is authorized to use the configured credentials.
+
+The most important premises are:
+
+> `oli` trusts the local user, selected config file, selected environment, and
+> selected storage endpoint as intentional inputs.
+>
+> `oli` must still preserve its own CLI boundary: it must not mix credentials
+> between profiles, sign requests for the wrong endpoint, leak secrets through
+> unintended output, or map local paths contrary to the documented operation.
+
+## 3. System Model
+
+An `oli` deployment has these participants:
+
+- Local user or script: Trusted invoker that chooses command arguments, config
+  path, profile, stdin, stdout and stderr handling, environment, and editor.
+- `oli` process: CLI that loads profile data, parses locations, creates
+  OpenDAL operators, streams data, prints output, and exits.
+- OpenDAL library: In-process storage abstraction used by `oli` to implement
+  service-specific operations, credential loading, request construction, and
+  signing.
+- Custom request signer or key provider: Code or configuration used through
+  OpenDAL to load credentials or sign requests for services that require
+  request signing.
+- Storage backend: Service selected by the trusted profile configuration, such
+  as S3-compatible object storage, Azure, GCS, HTTP, WebDAV, WebHDFS, or local
+  filesystem.
+- Local editor: Program selected by `$EDITOR` and invoked by `oli edit` with
+  object contents in a temporary file.
+- Local OS account and filesystem: Provides config files, environment
+  variables, temp directories, local paths, process permissions, and terminal
+  behavior.
+- Network and proxy environment: Carries requests to the configured storage
+  endpoint. TLS, proxies, DNS, and CA policy are primarily provided by OpenDAL
+  dependencies and the host environment.
+
+## 4. Assets
+
+The assets in scope are:
+
+- static access keys, secret keys, session tokens, bearer tokens, private key
+  material, service-account files, and custom signing keys;
+- signed requests, canonical request inputs, signature headers, query
+  signatures, and presigned URLs if exposed by a future command;
+- profile configuration from config files and `OLI_PROFILE_<PROFILE>_<OPTION>`
+  environment variables;
+- object bytes, object metadata, paths, directory names, roots, bucket names,
+  endpoints, and namespaces;
+- local files read or written by filesystem locations;
+- temporary files created for `oli edit`;
+- stdout, stderr, progress output, error chains, terminal transcripts, CI logs,
+  and shell history;
+- remote storage state modified by `cp`, `mv`, `rm`, `tee`, `edit`, and
+  `bench`.
+
+## 5. Trust Boundaries
+
+### 5.1 Command Line and Stdio
+
+Command-line arguments, stdin, stdout, and stderr are controlled by the local
+user or calling script. `oli` may display paths, metadata, benchmark paths,
+progress information, and object bytes because those are normal command
+results.
+
+Reports are in scope when `oli` prints credential material, signing secrets, or
+unexpectedly sensitive profile values outside commands whose purpose is to show
+configuration.
+
+### 5.2 Config Files and Environment
+
+`oli` loads profile configuration from the selected config file and overlays
+matching environment variables. Environment variables have higher precedence
+than the config file.
+
+The local user is responsible for protecting profile files and process
+environment. A local attacker who can edit the config file, control
+`--config`, or inject environment variables can redirect endpoints, change
+roots, change credential options, enable alternate credential sources, or cause
+requests to be signed with attacker-chosen settings.
+
+`oli` is responsible for applying the documented precedence consistently and
+for not leaking values that are credentials except through explicit local-admin
+inspection commands.
+
+### 5.3 Profiles, Endpoints, and Signing
+
+A profile is an authority boundary. Commands using profile `A` must use only
+profile `A` configuration, credentials, ambient credential chain, and custom
+signing setup. A command using profile `B` must not inherit secrets or signer
+state from profile `A` unless OpenDAL explicitly documents shared state 
selected
+by the user.
+
+When a profile signs requests, the signed host, endpoint, path, headers, query,
+method, body hash, timestamp, expiry, and credential scope must match the
+selected service's contract. `oli` delegates service-specific signing to
+OpenDAL and its signing integrations, but reports are still in scope for this
+repository if `oli` passes the wrong profile, path, endpoint, or operation into
+OpenDAL.
+
+If the user configures an attacker-controlled endpoint and gives it signing
+credentials, sending signed requests to that endpoint is user configuration,
+not an `oli` vulnerability. If `oli` ignores the configured endpoint or mixes 
it
+with another profile's credentials, that is in scope.
+
+### 5.4 Locations and Local Filesystem
+
+Locations in the form `<profile>:/<path>` use the named profile. Inputs without
+`:/` are treated as local filesystem locations through OpenDAL's filesystem
+service.
+
+`oli` must parse locations deterministically and reject unsupported host syntax
+such as `<profile>://host/path`. For local filesystem locations, `oli` runs 
with
+the local user's filesystem permissions. It is not a sandbox against the local
+user's own paths, existing symlinks, mount points, file permissions, or
+platform-specific filesystem behavior.
+
+Reports are in scope when `oli` maps a user-provided local path to a different
+location than its parser contract implies, or when a remote path is sent to a
+different profile than the one selected in the command.
+
+### 5.5 `oli edit`
+
+`oli edit` downloads object contents into a local temporary file, launches
+`$EDITOR`, reads the edited file, and uploads changed content.
+
+The selected editor, editor plugins, terminal, temp directory, swap files,
+backup files, and local OS account are part of the user's trusted computing
+base. `oli` is responsible for using a secure temporary-file primitive and for
+not leaving temporary files behind on successful upload. If upload fails, `oli`
+may preserve the edited file so the user does not lose changes; that preserved
+file is sensitive local data.
+
+### 5.6 Destructive and High-Cost Commands
+
+`rm`, recursive `rm`, `mv`, `cp`, `tee`, `edit`, and `bench` intentionally
+modify storage state. `bench` intentionally writes benchmark objects, may use
+parallelism, and may consume network, storage, and provider quota.
+
+The local user is responsible for choosing profiles, paths, benchmark sizes,
+parallelism, and retention options. Reports are in scope when `oli` modifies a
+path other than the selected operation's documented target, crosses profile
+boundaries, or fails to respect recursive versus non-recursive behavior.
+
+## 6. In-Scope Security Properties
+
+### 6.1 Credential and Key Isolation
+
+`oli` must not leak or reuse credentials, key material, custom signer state, or
+ambient credential results across independent profiles or commands.
+
+Examples:
+
+- `oli cp profile-a:/x profile-b:/y` must read with profile `A` and write with
+  profile `B`; profile `A` credentials must not sign profile `B` requests.
+- Environment overrides for one profile must not apply to another profile.
+- A custom signer configured for one service must not be used for another
+  service unless the user explicitly configures that sharing.
+
+### 6.2 Signing Correctness at the CLI Boundary
+
+`oli` must pass the intended operation, path, endpoint, profile data, and
+headers into OpenDAL. Request signing bugs inside OpenDAL or its signing
+subprojects should be reported against the component that owns the signer, but
+`oli` remains responsible for errors introduced by CLI parsing, profile merge,
+or command construction.
+
+Examples:
+
+- A destination upload must not be signed as a read operation.
+- Recursive copy must not construct destination paths that escape the selected
+  destination prefix.
+- A content-type override must not be silently applied to the wrong destination
+  object.
+
+### 6.3 Secret Redaction and Local Output
+
+`oli` must avoid exposing credentials through unintended debug output, error
+contexts, panic messages, progress output, and benchmark reports.
+
+`oli config view` is an explicit local inspection command and can reveal
+profile values to the local user. Users should treat its output as secret when
+profiles contain credentials. Future changes that make config inspection safer
+by default are hardening improvements, not a reduction of the current threat
+model.
+
+Paths, roots, endpoints, bucket names, object metadata, ETags, and sizes can be
+sensitive in some deployments, but they are normal operational output for a 
CLI.
+Deployments that treat them as confidential should control terminal logging and
+CI output.
+
+### 6.4 Path and Profile Binding
+
+`oli` must bind each command argument to the intended operator and object path.
+It must not accidentally swap source and destination profiles, interpret remote
+locations as local files, or treat unsupported URL host syntax as a valid
+profile location.
+
+### 6.5 Local Temporary Files
+
+Temporary files created by `oli` must use OS-provided secure temporary-file
+mechanisms. They must not use predictable names, follow attacker-controlled
+symlink paths, or overwrite unrelated files through `oli` path construction.
+
+### 6.6 Robustness
+
+`oli` must handle untrusted backend responses, malformed metadata, unexpected
+object names, and service errors without memory-safety violations, panics that
+expose secrets, or inconsistent local cleanup. Semantic correctness of backend
+data remains the backend's responsibility.
+
+## 7. Out of Scope
+
+The following are not `oli` vulnerabilities by default:
+
+- A user configures malicious credentials, an attacker-controlled endpoint, or
+  a profile root that points at sensitive storage.
+- A local attacker can edit the selected config file, control the process
+  environment, replace the `oli` binary, change `$EDITOR`, or read the user's
+  terminal output.
+- A storage backend lies about object bytes, metadata, ETags, timestamps,
+  listing order, authorization, or durability.
+- A provider-side bucket policy, IAM policy, OAuth scope, database permission,
+  or filesystem permission is too broad.
+- A script forwards untrusted tenant input into `oli` without its own
+  authentication, authorization, validation, or quoting.
+- A command intentionally prints object bytes, metadata, paths, or config 
values
+  to a terminal or log chosen by the user.
+- A user runs large recursive copies, recursive deletes, or benchmark workloads
+  that consume quota, bandwidth, storage, or memory.
+- TLS certificate policy, proxy configuration, DNS behavior, and CA bundles
+  selected by the host environment, unless `oli` introduces a separate option
+  that weakens them contrary to documentation.
+- General dependency freshness, CI hardening, release infrastructure, and ASF
+  infrastructure policy, unless a separate project policy says otherwise.
+
+## 8. Triage Dispositions
+
+Use these labels consistently:
+
+- `VALID`: The report shows a reachable violation of an in-scope `oli`
+  boundary, such as credential disclosure, cross-profile credential reuse,
+  wrong-path mutation, unsafe temp-file behavior, or CLI-induced signing error.
+- `VALID-UPSTREAM`: The report affects OpenDAL or a signing subproject rather
+  than `oli`'s CLI boundary. Coordinate disclosure and fix in the owning
+  component.
+- `VALID-HARDENING`: There is no clear boundary violation, but behavior is
+  risky or surprising enough that maintainers choose to harden docs, defaults,
+  warnings, or redaction.
+- `OUT-OF-SCOPE: local-control`: The report requires control of the local user
+  account, config file, environment, editor, terminal, binary, or process
+  supervisor.
+- `OUT-OF-SCOPE: caller-config`: The report depends on a trusted user selecting
+  a malicious endpoint, credential, root, signer, config path, or service
+  option.
+- `OUT-OF-SCOPE: backend`: The report depends on a configured backend being
+  malicious, compromised, semantically wrong, or misconfigured.
+- `OUT-OF-SCOPE: caller-authz`: The report depends on another application or
+  script passing unauthorized user input into `oli`.
+- `OUT-OF-SCOPE: expected-output`: The report is about output that the selected
+  command is designed to display to the local user.
+- `BY-DESIGN: property-not-provided`: The report asks `oli` to provide a
+  property explicitly not provided here, such as multi-tenant authorization,
+  endpoint trust decisions, backend-byte authentication, or default quota
+  control.
+- `MODEL-GAP`: The report cannot be classified by this document. Treat this as
+  evidence that the model needs revision.
+
+## 9. Examples
+
+These examples describe classes of reports, not a complete list of affected
+commands or services.
+
+### 9.1 In Scope
+
+- `oli cp a:/secret b:/copy` signs the destination write with profile `a`
+  credentials instead of profile `b` credentials.
+- `OLI_PROFILE_A_SECRET_ACCESS_KEY` unexpectedly changes any profile other than
+  profile `a`.
+- A malformed profile or backend response causes a panic that prints secret key
+  material in an error chain.
+- `oli edit` creates a predictable temporary path that another local user can
+  pre-create as a symlink.
+- Recursive copy constructs destination paths outside the selected destination
+  prefix.
+- A CLI parsing bug causes `profile:/path` to be sent to a different profile.
+
+### 9.2 Out of Scope By Default
+
+- A user stores long-lived cloud keys in `config.toml` with world-readable file
+  permissions.
+- A user sets `$EDITOR` to a program that exfiltrates temporary file contents.
+- A user configures an attacker-controlled S3-compatible endpoint and sends it
+  signed requests.
+- A storage provider accepts an overprivileged key and permits destructive
+  deletes.
+- `oli cat` prints sensitive object bytes to a terminal transcript.
+- A CI job runs `oli config view` and publishes the job log.
+- A benchmark workload consumes provider quota.
+
+## 10. Maintainer Decisions
+
+- Relation to OpenDAL: `oli` inherits OpenDAL service behavior and threat
+  boundaries where it delegates operation execution. CLI parsing, profile
+  merge, command semantics, local output, and temp files remain `oli`
+  responsibilities.
+- Custom signing: Custom signers and key providers are trusted when configured
+  by the user. `oli` must not cross-wire them between profiles or pass 
incorrect
+  request inputs into OpenDAL.
+- Config precedence: Environment profile variables override config-file profile
+  values. This is intentional and must be documented because environment
+  injection changes command authority.
+- Local filesystem: Local paths run with the local user's OS permissions. `oli`
+  is not a filesystem sandbox.
+- Config inspection: `oli config view` is a local inspection command. Its 
output
+  is sensitive when profile values are sensitive.
+- Backend trust: The configured backend is trusted for object bytes, metadata,
+  authorization decisions, consistency, and durability.
+- Object integrity: `oli` does not provide end-to-end cryptographic object
+  authentication above the configured backend. Users that require it must add 
it
+  outside `oli`.
+- Resource limits: `oli` does not provide default protection against
+  intentionally large reads, listings, copies, deletes, or benchmark workloads.
+
+## 11. Revision Triggers
+
+Update this threat model when any of the following changes:
+
+- `oli` adds commands for presigning, key management, credential generation, or
+  custom signer configuration;
+- config precedence, profile naming, or environment variable parsing changes;
+- commands add new local filesystem write surfaces or long-lived local caches;
+- `oli edit` changes temp-file preservation or editor invocation behavior;
+- request-signing behavior becomes directly implemented in this repository;
+- remote HTTP client, TLS, proxy, or endpoint policy becomes configurable by
+  `oli`;
+- output redaction behavior changes;
+- a vulnerability report is classified as `MODEL-GAP`.

Reply via email to