Skip to content

CONNECT AN API · GOOGLE DRIVE · 15 MINUTES

Connect Google Drive

Google Drive gives your agent three operations: create a folder, give one email address access to a file or folder, and read a file's bytes. The credential lives in your Enclave's vault on your own machine, and it never reaches EKKA.

Two properties are worth knowing before you start. An agent that can share a folder can only share to addresses you named: the allowlist is on the plan step, and it is checked inside your Enclave before anything is sent. And the connection is pinned inside Drive: the same Google credential could unlock Calendar, Sheets and the rest of Google's APIs, but every call on this connection outside Drive is refused as API_RULE_DENIED.

You need Google Workspace and someone who can create an OAuth client in your Google Cloud project. Connecting means obtaining a refresh token once and pasting it in. That is enrollment, and it happens a single time. A service account's JSON key is not a credential this connection can take.


Whose Drive should it be?

The agent works as the account that consents in step 2, and the folders it creates belong to that account. For anything a company relies on, use a shared Workspace user (an ops@ or hr@ account) rather than a person's own login, so the folders and the credential outlive whoever set them up.

A Google Group cannot be used

A group has no login, so it can neither consent nor own files. Make one real Workspace user and share what it owns with the group.

Step 1 · Create the OAuth client

The client lives inside your own Google organization, so the consent screen your people see belongs to your company.

  1. In Google Cloud Console, create a project and enable the Google Drive API.
  2. Under OAuth consent screen, choose Internal. An Internal client accepts accounts inside your Workspace and nowhere else, and its refresh tokens keep working. An External client left in Testing issues refresh tokens that stop working after seven days, which looks like EKKA breaking a week after you set it up.
  3. Under Credentials, create an OAuth client ID of type Web application, and add https://developers.google.com/oauthplayground as an authorized redirect URI.
  4. Copy the client ID and the client secret.

If you already made a client for Gmail, reuse it: enable the Drive API in the same project and skip to step 2.

Step 2 · Get a refresh token

Consent happens once, in Google's own tooling, and it produces the long-lived value EKKA stores. Google's OAuth 2.0 Playground does it without you writing any code.

  1. Open the Playground, click the settings gear, and tick Use your own OAuth credentials. Paste the client ID and client secret from step 1.
  2. In the scope box enter https://www.googleapis.com/auth/drive, then click Authorize APIs.
  3. Sign in as the account whose Drive the agent should work in, and click Allow.
  4. Click Exchange authorization code for tokens, and copy the refresh token.

Why the scope is drive and not drive.file

drive.file only reaches files the connected app itself created. A file a person uploads by hand, which is the whole point of a shared intake folder, would be invisible to the agent. drive sees what the account sees. Google lists what you granted at myaccount.google.com/permissions, which is also where you revoke it.

Step 3 · Connect it on this machine

ekka api connect google-drive --input client_id=<your client id>

It asks for the credential at a prompt. Paste the client secret and the refresh token, joined by a colon:

<client secret>:<refresh token>

For example, GOCSPX-aBc123:1//0gLmXyz.... A colon inside the refresh token is fine, because only the first colon splits the two values.

ekka api connect takes the credential from a prompt, or from --stdin in a script. It is never a command-line argument, so it never appears in shell history or in the process list.

What is written where

The secret goes into this machine's encrypted vault. The connection record beside it holds the address, the shape of the credential and its reference, and no values at all. A connection is per machine, because the credential lives on the machine and never leaves it.

Step 4 · Let an agent use it

connect prints this with your values already filled in:

ekka gate grant add --type api --resource apis/google-drive \
  --capability api.read --no-fingerprint

api.read lets an agent read a file's bytes. Add a second grant with api.write when you want it to create folders and share them.

Until you run this, nothing can touch the Drive. Connecting and permitting are two separate decisions, so a connection sitting on a machine is not access.

Step 5 · Check it works

ekka api test google-drive

It checks four things in order and prints a row for each: the config it will use, whether the credential is in the vault, whether a grant allows the operation, and a live call to GET /drive/v3/about. The live row is a real call to Google rather than a guess from stored state.

It exits 0 when the connection works, 1 when something is wrong, and 2 when a check could not be performed. A check that cannot run says so and never reports as a pass.


What can a plan do?

Three operations. See the exact fields with ekka api spec google-drive.

Call What it does Needs
createFolder make a folder inside a parent folder name, parentId
setPermission give one email access to a file or folder fileId, role, type, emailAddress, and a recipients list
getFileContent read a file's raw bytes fileId

A folder's id is the last part of its URL when you open it in Drive: drive.google.com/drive/folders/1AbC....

Create an intake folder for a new hire:

{ "id": "folder", "action_ref": "ekka.gate.api.v1",
  "target": "<your api gate>", "op": "write", "call": "createFolder",
  "inputs": { "resource": "apis/google-drive",
              "name": "@input.candidate",
              "parentId": "1AbCdEfGhIjKlMnOpQrStUvWxYz" } }

Share it with the candidate:

{ "id": "share", "action_ref": "ekka.gate.api.v1",
  "target": "<your api gate>", "op": "write", "call": "setPermission",
  "inputs": { "resource": "apis/google-drive",
              "fileId": "@input.folder",
              "role": "writer", "type": "user",
              "emailAddress": "@input.candidate_email",
              "recipients": ["*@acme.com"] } }

role is reader, writer or commenter. A value may be @input.<name> to take it from the run. The target is your Enclave's api gate, and ekka gate list names it.

Who may your agent share with?

setPermission will not run without a recipients list. It is not a setting you can leave off:

"recipients": ["*@acme.com", "[email protected]"]

Write whole addresses, or *@domain for everyone at a domain.

The check runs inside your Enclave, before anything is sent, so an address outside the list never becomes access. That matters because the address usually comes from the run rather than from the plan's author: your plan does not know at authoring time who the candidate is. The allowlist is what makes "the agent decides who to share with" safe to write down.

Why you cannot allow everyone

A bare * is refused. There is no way to spell "any recipient", because a list that permitted everything would read like a protection while being none, and reviewing it would tell you nothing.

What can an agent not do here, even with a grant?

  • It cannot leave Drive. Every call on this connection must sit under /drive/v3/. The credential's other Google APIs answer API_RULE_DENIED before anything is sent.
  • It cannot read a native Google Doc. A Doc, Sheet or Slide has no bytes of its own; getFileContent reads real uploaded files, like a PDF someone dropped into a folder.
  • A big file is not a download. A read larger than 10 MiB is cut, and the receipt says truncated.
  • Govern never sees your files. The bytes travel between Google and your Enclave. The control plane authorizes the call and signs the receipt without the content crossing it.
  • Revoking is immediate. An access token is issued fresh for every call and nothing is cached. Remove EKKA at myaccount.google.com/permissions and the very next call fails.

How do I turn it off?

ekka gate grant list                        # find the grant
ekka gate grant revoke <grant-id>           # the next attempt is refused, live
ekka api disconnect google-drive            # remove the connection from this machine

Revoking the grant stops the agent. Disconnecting removes the credential from this machine's vault. Revoking consent in your Google account stops it at the other end, and any of the three is enough on its own.