Skip to content

FileArtifactService stores artifacts outside the app namespace #5618

@Nant361

Description

@Nant361

Required Information

Describe the Bug:

FileArtifactService accepts app_name in its public artifact APIs, but the file backend stores data under root/users/{user_id}/.... The on-disk path does not include app_name.

This differs from the API boundary and the other artifact service implementations. Two apps that share the same file artifact root can resolve the same file path when user_id, session_id, and filename match.

Steps to Reproduce:

  1. Create one FileArtifactService with a shared root_dir.
  2. Save an artifact with app_name="app_a", a fixed user_id, session_id, and filename.
  3. Load or list artifacts with app_name="app_b" and the same user_id, session_id, and filename.
  4. The file backend resolves the same artifact path because the app name is not part of the directory layout.

Expected Behavior:

File-backed artifacts should be isolated by app_name, user_id, session_id, and filename, matching the BaseArtifactService API boundary and the other artifact backends.

Observed Behavior:

FileArtifactService stores artifacts below root/users/{user_id}/..., so app_name does not affect the on-disk namespace.

Environment Details:

  • ADK Library Version: source checkout from main at 153c7f70931018ed1687716d4bee7ffe2fd917ac
  • Desktop OS: macOS 26.4.1
  • Python Version: Python 3.12.11

Model Information:

  • Are you using LiteLLM: No
  • Which model is being used: N/A

Optional Information

Regression:

Unknown.

Logs:

N/A

Screenshots / Video:

N/A

Additional Context:

I have a small patch ready that adds a validated app_name path segment to the file storage layout and adds regression coverage for cross-app isolation.

Minimal Reproduction Code:

from google.adk.artifacts.file_artifact_service import FileArtifactService
from google.genai import types

service = FileArtifactService(root_dir="/tmp/adk-artifacts")

await service.save_artifact(
    app_name="app_a",
    user_id="user123",
    session_id="sess123",
    filename="report.txt",
    artifact=types.Part(text="app A data"),
)

part = await service.load_artifact(
    app_name="app_b",
    user_id="user123",
    session_id="sess123",
    filename="report.txt",
)

assert part is None

How often has this issue occurred?:

Always (100%)

Metadata

Metadata

Labels

services[Component] This issue is related to runtime services, e.g. sessions, memory, artifacts, etc

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions