# gogcli Auth Flags: Understanding --readonly vs --drive-scope

> Understand gogcli Auth flags --readonly vs --drive-scope. Learn how each flag uniquely controls Google service and Drive permissions for secure access.

- Repository: [Peter Steinberger/gogcli](https://github.com/steipete/gogcli)
- Tags: understanding
- Published: 2026-02-16

---

**The `--readonly` flag restricts all Google services to read-only access while forcing Drive to `drive.readonly`, whereas `--drive-scope` independently configures Drive permissions (full, readonly, or file) without affecting other services.**

When authenticating with Google APIs through the `gogcli` tool (steipete/gogcli), you must define OAuth 2.0 scopes that determine what the generated refresh token can access. The `gog auth add` command provides two distinct flags—`--readonly` and `--drive-scope`—that control these permissions at different granularities. Understanding how these flags interact is critical for implementing the principle of least privilege in your Google Workspace automations.

## What the --readonly Flag Controls

The `--readonly` flag, defined in [`internal/cmd/auth.go`](https://github.com/steipete/gogcli/blob/main/internal/cmd/auth.go) (lines 486-488), modifies the scope selection logic to request read-only variants of every supported Google service that offers them. When enabled, the authentication flow automatically includes standard OIDC identity scopes (`openid`, `email`, `userinfo.email`) alongside service-specific read-only scopes such as `gmail.readonly`, `calendar.readonly`, and `spreadsheets.readonly`.

The scope calculation logic resides in [`internal/googleauth/service.go`](https://github.com/steipete/gogcli/blob/main/internal/googleauth/service.go). The `scopesForServiceWithOptions` function (lines 20-30) handles the per-service mapping, while the `driveScopeValue()` helper (lines 98-115) specifically manages Drive permissions. When `--readonly` is active, `driveScopeValue()` returns `drive.readonly` regardless of other settings, unless explicitly overridden by `--drive-scope`.

## What the --drive-scope Flag Configures

The `--drive-scope` flag provides granular control specifically for Google Drive permissions without affecting other services. Defined alongside `--readonly` in [`internal/cmd/auth.go`](https://github.com/steipete/gogcli/blob/main/internal/cmd/auth.go), this flag accepts three distinct modes:

- **full** (default): Requests `https://www.googleapis.com/auth/drive`, granting complete access to all Drive files and folders
- **readonly**: Requests `drive.readonly`, permitting only read operations
- **file**: Requests `drive.file`, which grants write access only to files created or opened by the application, providing a restricted write capability

The implementation in [`internal/googleauth/service.go`](https://github.com/steipete/gogcli/blob/main/internal/googleauth/service.go) processes this through the `ScopeOptions` struct (lines 49-52), which carries both flag values to the scope calculation functions. When `--readonly` is false, `driveScopeValue()` returns the scope corresponding to the `--drive-scope` setting; otherwise, it defaults to `drive.readonly`.

## Critical Interactions and Validation Rules

These flags interact in specific ways that trigger validation errors when misconfigured. The command-line parser in [`internal/cmd/auth.go`](https://github.com/steipete/gogcli/blob/main/internal/cmd/auth.go) (lines 507-508) explicitly forbids combining `--readonly` with `--drive-scope=file` because `drive.file` inherently grants write capabilities, contradicting the read-only restriction.

When both flags are present but valid (e.g., `--readonly` with `--drive-scope=readonly`), the `--readonly` flag takes precedence for Drive permissions, forcing `drive.readonly` regardless of the explicit drive scope setting. This ensures that the global read-only restriction cannot be inadvertently bypassed through specific service configuration.

## Practical Usage Examples

The following examples demonstrate common authentication scenarios using these flags.

Request read-only access across all services including Drive:

```bash
gog auth add user@example.com \
    --services gmail,calendar,drive \
    --readonly

```

This generates scopes: `openid`, `email`, `userinfo.email`, `gmail.readonly`, `calendar.readonly`, `drive.readonly`.

Grant full Gmail and Calendar access with restricted Drive file access:

```bash
gog auth add user@example.com \
    --services gmail,calendar,drive \
    --drive-scope=file

```

This produces: `gmail.modify`, `calendar`, `drive.file` (plus OIDC scopes), allowing write access only to Drive files created by the application.

Attempting to combine conflicting flags results in an error:

```bash
gog auth add user@example.com \
    --services drive \
    --readonly \
    --drive-scope=file

```

The command aborts with: "cannot combine --readonly with --drive-scope=file (file is write-capable)".

## Summary

- The `--readonly` flag enforces read-only access across all Google services, automatically selecting `drive.readonly` for Drive permissions
- The `--drive-scope` flag independently configures Drive access levels (full, readonly, file) without affecting other services
- These flags conflict when `--drive-scope=file` is combined with `--readonly`, triggering a validation error in [`internal/cmd/auth.go`](https://github.com/steipete/gogcli/blob/main/internal/cmd/auth.go)
- Scope calculation logic resides in [`internal/googleauth/service.go`](https://github.com/steipete/gogcli/blob/main/internal/googleauth/service.go), specifically within `driveScopeValue()` and `scopesForServiceWithOptions()`

## Frequently Asked Questions

### Can I use --drive-scope=full with --readonly?

No. When `--readonly` is specified, it overrides any Drive scope setting to `drive.readonly`. The `driveScopeValue()` function in [`internal/googleauth/service.go`](https://github.com/steipete/gogcli/blob/main/internal/googleauth/service.go) checks the `Readonly` field first, returning the read-only variant regardless of the `DriveScope` setting.

### What happens if I omit both flags?

The command requests full access scopes for all selected services. For Drive, this means `https://www.googleapis.com/auth/drive`, granting complete read and write access to all files and folders in the user's Google Drive.

### Why does --drive-scope=file conflict with --readonly?

The `drive.file` scope grants write access to files created or opened by the application, which contradicts the global read-only restriction implied by `--readonly`. The validation logic in [`internal/cmd/auth.go`](https://github.com/steipete/gogcli/blob/main/internal/cmd/auth.go) (lines 507-508) explicitly checks for this combination and aborts with an error to prevent accidental privilege escalation.

### Which services support read-only variants when using --readonly?

The implementation in [`internal/googleauth/service.go`](https://github.com/steipete/gogcli/blob/main/internal/googleauth/service.go) provides read-only mappings for Gmail (`gmail.readonly`), Google Calendar (`calendar.readonly`), Google Sheets (`spreadsheets.readonly`), and Google Drive (`drive.readonly`). Other services without explicit read-only variants in the codebase default to their standard scopes or are omitted based on the service selection.