> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Service Account Authentication - Google Sheets API for Laravel

> Configure Service Account authentication for Google Sheets API. Best for server-to-server access.

Service Account authentication is ideal for server-to-server access to Google Sheets that your application controls or has been granted access to. This method requires no user interaction and is perfect for automated systems, background jobs, and applications that need to access specific spreadsheets programmatically.

## When to Use Service Account

* **Server-to-server access** — Your application accesses Google Sheets without user interaction
* **Automated systems** — Background jobs, cron tasks, automated reporting
* **Fixed spreadsheet access** — Working with specific spreadsheets you control
* **Production applications** — Reliable authentication without user consent flows

## Prerequisites

* Google Cloud Console project
* Google Sheets API and Google Drive API enabled
* Project admin access to create Service Accounts

## Setup Steps

<Steps>
  <Step title="Create a Google Cloud Project">
    1. Go to [Google Cloud Console](https://console.cloud.google.com/)
    2. Create a new project or select an existing one
    3. Note your project ID for later use
  </Step>

  <Step title="Enable Required APIs">
    1. Navigate to **APIs & Services** > **Library**
    2. Search for and enable:
       * **Google Sheets API**
       * **Google Drive API**
  </Step>

  <Step title="Create a Service Account">
    1. Go to **APIs & Services** > **Credentials**
    2. Click **Create Credentials** > **Service Account**
    3. Fill in the details:
       * **Service account name**: Descriptive name (e.g., "Laravel Sheets App")
       * **Service account ID**: Auto-generated
       * **Description**: Optional
    4. Click **Create and Continue**
    5. Skip optional sections and click **Done**
  </Step>

  <Step title="Generate Service Account Key">
    1. In the **Credentials** page, click on your Service Account
    2. Go to the **Keys** tab
    3. Click **Add Key** > **Create new key**
    4. Choose **JSON** as the key type
    5. Click **Create**
    6. The JSON file will download automatically
  </Step>

  <Step title="Store the JSON File">
    1. Move the downloaded JSON to your `storage/app/` directory
    2. Rename it to `google-service-account.json`
    3. **Important**: Add to `.gitignore` to exclude from version control

    ```bash theme={null}
    # Add to .gitignore
    storage/app/google-service-account.json
    ```
  </Step>

  <Step title="Configure .env File">
    Add to your `.env`:

    ```env theme={null}
    GOOGLE_SERVICE_ENABLED=true
    GOOGLE_SERVICE_ACCOUNT_JSON_LOCATION=storage/app/google-service-account.json
    ```
  </Step>

  <Step title="Set Scopes in config/google.php">
    ```php theme={null}
    'scopes' => [
        \Google\Service\Sheets::SPREADSHEETS,
        \Google\Service\Drive::DRIVE,
    ],
    ```
  </Step>

  <Step title="Share Spreadsheets with Service Account">
    For each Google Sheet you want to access:

    1. Open the spreadsheet
    2. Click **Share**
    3. Get the `client_email` from your JSON file
    4. Share the sheet with this email (format: `your-service-account@your-project-id.iam.gserviceaccount.com`)
    5. Grant permissions:
       * **Viewer** — Read-only
       * **Editor** — Read and write
       * **Owner** — Full access (not recommended)
  </Step>
</Steps>

## Usage

Once configured, Service Account authentication works automatically:

```php theme={null}
use Revolution\Google\Sheets\Facades\Sheets;

// Service Account is used automatically
$values = Sheets::spreadsheet('your-spreadsheet-id')
    ->sheet('Sheet1')
    ->all();

// Reference by spreadsheet title (requires Drive API)
$values = Sheets::spreadsheetByTitle('My Spreadsheet')
    ->sheet('Sheet1')
    ->all();
```

## Security Best Practices

### 1. Limit Service Account Permissions

* Only grant access to necessary spreadsheets
* Use **Editor** instead of **Owner** when possible
* Regularly audit which spreadsheets have access

### 2. Secure Key Storage

* Never commit service account keys to version control
* Use environment variables for key file paths
* Store keys outside the web root in production
* Rotate keys periodically

### 3. Production Deployment

Additional security measures:

* Store JSON key in a secure location outside web root
* Use separate Service Accounts for different environments (dev, staging, production)
* Monitor account usage through Google Cloud Console
* Set up logging and alerts for suspicious activity

## Environment Variables Reference

| Variable                               | Description                 | Example                                   |
| -------------------------------------- | --------------------------- | ----------------------------------------- |
| `GOOGLE_SERVICE_ENABLED`               | Enable service account auth | `true`                                    |
| `GOOGLE_SERVICE_ACCOUNT_JSON_LOCATION` | Path to JSON key file       | `storage/app/google-service-account.json` |

## Advanced Configuration

### Using JSON String in Environment Variable

Store the service account credentials as a JSON string instead of a file, ideal for CI/CD environments like GitHub Actions.

**Step 1: Store JSON string in .env**

```env theme={null}
GOOGLE_SERVICE_ENABLED=true
GOOGLE_SERVICE_ACCOUNT_JSON_LOCATION='{"type": "service_account", "project_id": "your-project-id", ...}'
```

**Step 2: Decode in config/google.php**

```php theme={null}
// config/google.php
'service' => [
    'enable' => env('GOOGLE_SERVICE_ENABLED', false),
    'file' => json_decode(env('GOOGLE_SERVICE_ACCOUNT_JSON_LOCATION', ''), true),
],
```

This approach eliminates the need for a separate file and simplifies CI/CD deployments.

## Troubleshooting

### Common Errors

**"caller does not have permission" error**

* Verify the spreadsheet is shared with the Service Account email
* Ensure permissions are **Editor** or higher for write operations

**"File not found" error**

* Check the JSON file path is correct
* Ensure the file exists and is readable by the web server

**"API not enabled" error**

* Verify Google Sheets API and Google Drive API are enabled
* Wait a few minutes for changes to propagate

**"Invalid credentials" error**

* Verify the JSON key file is valid and not corrupted
* Ensure the Service Account hasn't been deleted or disabled
* Check that the project ID matches your Google Cloud project

### Test Your Setup

Create a test route to verify Service Account setup:

```php theme={null}
// routes/web.php
Route::get('/test-sheets', function () {
    try {
        $sheets = Sheets::spreadsheetList();
        return response()->json([
            'status' => 'success',
            'message' => 'Service Account authentication is working',
            'spreadsheet_count' => count($sheets)
        ]);
    } catch (\Exception $e) {
        return response()->json([
            'status' => 'error',
            'message' => $e->getMessage()
        ]);
    }
});
```

Access this route to verify your configuration.
