# How Apollo Save Tool Integrates with the Orbis SaveData API for PS4 Save Mounting

> Discover how Apollo Save Tool integrates with Orbis SaveData API to mount PS4 saves. Learn about C wrappers, key decryption, and filesystem mounting under data apollo mount.

- Repository: [Damián Parrino/apollo-ps4](https://github.com/bucanero/apollo-ps4)
- Tags: how-to-guide
- Published: 2026-02-26

---

**Apollo Save Tool uses a two-layer C wrapper in [`source/saves.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/saves.c) and [`source/sd.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/sd.c) to call `sceFsMountSaveData` and `sceFsUmountSaveData`, decrypting sealed keys and sandboxing mounts under `/data/apollo/mount/` before exposing PS4 save data as a standard filesystem.**

The **Apollo Save Tool** (bucanero/apollo-ps4) provides homebrew utilities for managing PlayStation 4 save files by integrating directly with Sony's **Orbis SaveData API**. Understanding how Apollo Save Tool integrates with the Orbis SaveData API reveals the cryptographic and filesystem layers required to mount encrypted PS4 save data as accessible directories.

## Architecture Overview

Apollo implements a clean separation between high-level save management and low-level Orbis kernel calls. The **high-level logic** resides in [`source/saves.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/saves.c), handling sandbox creation, SQLite metadata tracking, and user-facing functions like `orbis_SaveMount()` and `orbis_SaveUmount()`. The **low-level implementation** in [`source/sd.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/sd.c) contains the cryptographic wrappers that invoke the actual Orbis FS syscalls `sceFsMountSaveData()` and `sceFsUmountSaveData()`.

## Mounting PS4 Save Data with the Orbis API

The mount operation follows a strict sequence to ensure encrypted save images are properly decrypted and isolated before user access.

### Building the Sandbox Environment

Before calling the kernel, `orbis_SaveMount()` constructs a unique sandbox directory under `APOLLO_SANDBOX_PATH` (`/data/apollo/mount/%s/`). This path serves as the mount point where the decrypted filesystem will appear. The function ensures the directory exists and is empty, preventing cross-contamination between different save operations.

### Handling Sealed Keys and Encryption

Apollo must decrypt the **sealed key** stored alongside the save image before the kernel can mount it. Inside `mountSave()` ([`source/sd.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/sd.c)), the tool reads the `.bin` key file and calls `decryptSealedKeyAtPath()` to extract the raw decryption key. This key is passed directly to the Orbis FS layer and is never written to disk unencrypted.

### Calling sceFsMountSaveData

With the sandbox ready and key decrypted, `mountSave()` initializes the mount options structure via `sceFsInitMountSaveDataOpt()`, sets the budget ID to `"system"`, and executes:

```c
sceFsMountSaveData(&opt, volumePath, mountPath, decryptedSealedKey);

```

This syscall attaches the encrypted save image (located at `volumePath`) to the sandbox directory (`mountPath`), transparently decrypting it and exposing the contents as standard files.

## Unmounting Save Data Safely

Unmounting reverses the mount process while ensuring data integrity. The `orbis_SaveUmount()` function in [`source/saves.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/saves.c) reconstructs the sandbox path and delegates to `umountSave()` in [`source/sd.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/sd.c).

Inside `umountSave()`, the code initializes unmount options with `sceFsInitUmountSaveDataOpt()` and calls:

```c
sceFsUmountSaveData(&opt, mountPath, handle, ignoreErrors);

```

This detaches the filesystem, flushes any pending writes to the encrypted image, and invalidates the mount point. Apollo then cleans up the sandbox directory to free resources.

## Alternative API for Application Settings

While `sceFsMountSaveData` handles user save data, Apollo uses the higher-level **Orbis SaveData API** for its own configuration. In [`source/settings.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/settings.c), the tool calls `sceSaveDataMount2()` and `sceSaveDataUmount()` to manage the `savedata.db` SQLite database and binary config files. This API abstracts away the sealed-key mechanics, making it suitable for simple app-specific storage rather than complex encrypted save images.

## Code Example: Mounting and Unmounting in Practice

The following pattern demonstrates the complete lifecycle as implemented in the Apollo Save Tool:

```c
#include "saves.h"

/* Mount a PS4 save */
save_entry_t *save = find_save_by_title_id("CUSA12345");
char mount_path[ORBIS_SAVE_DATA_DIRNAME_DATA_MAXSIZE];

if (orbis_SaveMount(save, SAVE_FLAG_PS4, mount_path)) {
    LOG("Save mounted at: %s", mount_path);
    
    /* Perform file operations on the decrypted save data */
    /* ... */
    
    /* Unmount when finished */
    if (orbis_SaveUmount(mount_path)) {
        LOG("Save unmounted successfully");
    } else {
        LOG("Unmount failed");
    }
} else {
    LOG("Mount failed");
}

```

This example reflects the actual API surface in [`source/saves.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/saves.c), handling both the mount path output and proper cleanup.

## Key Source Files in the Apollo Repository

Understanding the Orbis SaveData API integration requires examining these specific files in the bucanero/apollo-ps4 repository:

- **[`source/saves.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/saves.c)** – Contains `orbis_SaveMount()` and `orbis_SaveUmount()`, handling sandbox path construction, SQLite metadata updates, and delegation to low-level helpers.
- **[`source/sd.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/sd.c)** – Implements `mountSave()` and `umountSave()`, wrapping `sceFsMountSaveData()` and `sceFsUmountSaveData()` with sealed-key decryption.
- **[`include/saves.h`](https://github.com/bucanero/apollo-ps4/blob/main/include/saves.h)** – Defines public structures like `save_entry_t` and mount flags (`SAVE_FLAG_PS4`, `SAVE_FLAG_TROPHY`, `SAVE_FLAG_LOCKED`).
- **[`source/settings.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/settings.c)** – Demonstrates the alternative `sceSaveDataMount2()` API for Apollo's internal configuration storage.
- **[`include/settings.h`](https://github.com/bucanero/apollo-ps4/blob/main/include/settings.h)** – Contains `app_config_t` structure definitions for settings management.

## Summary

- Apollo Save Tool integrates with the **Orbis SaveData API** through a two-layer C wrapper that separates high-level save management from kernel filesystem calls.
- **Mounting** involves creating sandbox directories under `/data/apollo/mount/`, decrypting sealed keys via `decryptSealedKeyAtPath()`, and invoking `sceFsMountSaveData()` to attach encrypted save images.
- **Unmounting** uses `sceFsUmountSaveData()` to detach filesystems and flush data, followed by sandbox cleanup in `orbis_SaveUmount()`.
- The repository uses the higher-level `sceSaveDataMount2()` API in [`source/settings.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/settings.c) for application-specific configuration storage.
- All operations are implemented in [`source/saves.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/saves.c) and [`source/sd.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/sd.c) within the bucanero/apollo-ps4 repository.

## Frequently Asked Questions

### What is the difference between sceFsMountSaveData and sceSaveDataMount2?

**sceFsMountSaveData** is a low-level filesystem API that mounts encrypted save images directly using decrypted sealed keys, requiring manual sandbox management. **sceSaveDataMount2** is a higher-level API that abstracts key handling and mounting into a single call, used primarily for application settings rather than user save data manipulation.

### How does Apollo Save Tool handle encrypted PS4 save files?

Apollo decrypts the **sealed key** stored alongside the save image using `decryptSealedKeyAtPath()` in [`source/sd.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/sd.c). This decrypted key is passed to `sceFsMountSaveData()`, which transparently decrypts the save image and exposes it as a standard directory under `/data/apollo/mount/`.

### Where does Apollo Save Tool store mounted save data temporarily?

Mounted saves are isolated in sandbox directories under **`/data/apollo/mount/<save_id>/`**, defined as `APOLLO_SANDBOX_PATH`. This ensures each save is mounted in an isolated environment and prevents conflicts between different save operations.

### What happens if the save file doesn't exist when mounting?

When the `ORBIS_SAVE_DATA_MOUNT_MODE_CREATE2` flag is set and the key file is missing, `orbis_SaveMount()` calls `createSave()` to generate a new encrypted save image and inserts a corresponding entry into the local `savedata.db` SQLite database before proceeding with the mount operation.