oci_osfs
A Drupal 10/11 stream wrapper module that integrates Oracle Cloud Infrastructure (OCI) Object Storage as a filesystem using the AWS SDK for PHP with S3-compatible API.
Features
Core Functionality
-
🗂️ Stream Wrapper - Full S3-based implementation for
oci://scheme - 📁 File Operations - Complete support: read, write, delete, rename, stat
- ⚡ Metadata Caching - Performance optimization with configurable TTL
- 🔗 Presigned URLs - 7-day signed URLs for public file access
- 🖼️ Image Styles - Support for image derivatives with custom routing
-
🔄 Optional Override - Can replace
public://andprivate:// - 📦 Prefix-based Mapping - Organize files with folder-like structure
Administration Interface
-
⚙️ Settings Page (
/admin/config/media/oci-osfs)- Credential management (Admin UI or settings.php)
- Region, Namespace, Bucket configuration
- Delivery methods and cache settings
- Visual credential status feedback
-
🔧 Actions Page (
/admin/config/media/oci-osfs/actions)- Validate Configuration - Test OCI connection
- Refresh Metadata Cache - Clear file metadata cache
- Copy Local Files to OCI - Batch migration tool
- Tab navigation between Settings and Actions
Authentication
- 🔑 Auto-detection - Automatically selects best authentication method
- 🎛️ Flexible Storage - Configure via Admin UI OR settings.php
-
Multiple Methods Supported:
- Customer Secret Keys (S3-compatible) - ⭐ Recommended
- API Key (native OCI SDK)
- Instance Principals (for OCI Compute instances)
Migration Tools
- 📤 Batch Processing - Handle large file sets efficiently
- ✅ Skip Existing Files - Avoid duplicate uploads
- 🎯 Scheme Selection - Choose public://, private://, or both
- 📊 Progress Tracking - Real-time migration status
Security
- 🔒 Path Traversal Protection - Multiple validation layers
- ✓ Input Validation - Comprehensive sanitization
- ⏱️ Rate Limiting - Configurable per-operation limits
- 📝 Security Logging - Track access attempts and events
- 🔐 Credential Validation - Verify all OCI identifiers
- 🚫 No Hardcoded Credentials - Secure credential management
Installation
Method 1: Install via Composer (Recommended)
When you install the module via Composer, all dependencies are automatically installed:
# From your Drupal root directory
composer require drupal/oci_osfs
# Enable module
drush en oci_osfs -y
drush cr
The aws/aws-sdk-php package will be installed automatically as a dependency.
Method 2: Manual Installation (Custom Module)
If you're installing from a custom module directory:
# Navigate to module directory
cd web/modules/custom/oci_osfs
# Install dependencies
composer install
# Enable module
drush en oci_osfs -y
drush cr
Verify Installation
# Check routes are registered
drush route | grep oci_osfs
# Expected output:
# oci_osfs.settings → /admin/config/media/oci-osfs
# oci_osfs.actions → /admin/config/media/oci-osfs/actions
# oci_osfs.image_style → /system/files/styles/{image_style}/oci
Quick Start
You can configure credentials through Admin UI (development) or settings.php (production):
Method A: Admin UI Configuration (Development)
-
Enable the module:
drush en oci_osfs -y && drush cr -
Visit Settings Page:
Navigate to/admin/config/media/oci-osfs -
Configure Credentials:
- Uncheck "Use credentials from settings.php instead of form"
- Enter your Access Key ID and Secret Access Key
- Configure Region, Namespace, and Bucket
- Save configuration
-
Test Connection:
Visit/admin/config/media/oci-osfs/actionsand click "Validate"
⚠️ Note: For production environments, use Method B for better security.
Method B: Settings.php Configuration (Production)
Step 1: Get Your OCI Credentials
For Customer Secret Keys (Recommended):
- Go to OCI Console → Profile → User Settings
- Click "Customer Secret Keys" → "Generate Secret Key"
- Copy the Access Key and Secret Key
For API Key:
- Go to OCI Console → Profile → User Settings
- Click "API Keys" → "Add API Key"
- Download the private key and note the fingerprint
Step 2: Create .env File
Create .env in your project root:
For Customer Secret Keys:
OCI_ACCESS_KEY="your-access-key-here"
OCI_SECRET_KEY="your-secret-key-here"
OCI_OBJECT_NAMESPACE="your-namespace"
OCI_REGION="me-jeddah-1"
OCI_OBJECT_BUCKET="your-bucket-name"
⚠️ Important: Add .env to your .gitignore!
Step 3: Configure settings.php
Add to web/sites/default/settings.php:
// Load .env file (for local development)
$env_file = $app_root . '/../.env';
if (file_exists($env_file)) {
$env_lines = file($env_file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($env_lines as $line) {
if (strpos(trim($line), '#') === 0 || strpos($line, '=') === false) {
continue;
}
list($name, $value) = explode('=', $line, 2);
$name = trim($name);
$value = trim($value, " \t\n\r\0\x0B\"'");
if (!getenv($name)) {
putenv("$name=$value");
}
}
}
// Customer Secret Keys (S3-compatible) - RECOMMENDED
$settings['oci_osfs.customer_keys'] = [
'access_key' => getenv('OCI_ACCESS_KEY'),
'secret_key' => getenv('OCI_SECRET_KEY'),
];
// Allow oci:// scheme for image styles
$settings['file_additional_public_schemes'] = ['oci'];
Step 4: Configure Module Settings
Visit /admin/config/media/oci-osfs and configure:
-
Region (e.g.,
me-jeddah-1) - Namespace (your Object Storage namespace)
- Bucket (your bucket name)
- Public/Private prefixes
- Delivery methods
Step 5: Test
# Test file upload
drush php:eval "file_put_contents('oci://test.txt', 'Hello OCI!');"
# Verify file exists
drush php:eval "echo file_get_contents('oci://test.txt');"
# Or use the Actions page
# Visit /admin/config/media/oci-osfs/actions and click "Validate"
Administration
Settings Page: /admin/config/media/oci-osfs
Credentials Section:
- Toggle between Admin UI and settings.php credential storage
- Visual feedback showing configured credentials
- Security warnings for database storage
Configuration Options:
-
Region: OCI region (e.g.,
me-jeddah-1,us-phoenix-1) - Namespace: Object Storage namespace
- Bucket: Bucket name for file storage
- Root Prefix: Optional base prefix inside the bucket
-
Public Prefix: Prefix for public:// files (default:
public) -
Private Prefix: Prefix for private:// files (default:
private) - Override public://: Use OCI for public files
- Override private://: Use OCI for private files
- Public Delivery: Direct URLs or Drupal-managed
- Private Delivery: Drupal-managed or signed URLs
- Metadata Cache TTL: Cache duration in seconds
Actions Page: /admin/config/media/oci-osfs/actions
1. Validate Configuration
- Tests the connection to OCI Object Storage
- Verifies credentials and bucket access
- Shows region, namespace, and bucket information
- Displays connection status
2. Refresh Metadata Cache
- Clears all file metadata cache
- Useful after manual bucket changes
- Forces fresh metadata on next file access
3. Copy Local Files to OCI
- Batch migration of existing files
-
Choose which scheme:
public://,private://, or both - Progress tracking for large migrations
- Automatically skips files already in OCI
- Safe to re-run (idempotent)