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.
- In Google Cloud Console, create a project and enable the Google Drive API.
- 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.
- Under Credentials, create an OAuth client ID of type Web
application, and add
https://developers.google.com/oauthplaygroundas an authorized redirect URI. - 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.
- Open the Playground, click the settings gear, and tick Use your own OAuth credentials. Paste the client ID and client secret from step 1.
- In the scope box enter
https://www.googleapis.com/auth/drive, then click Authorize APIs. - Sign in as the account whose Drive the agent should work in, and click Allow.
- 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¶
It asks for the credential at a prompt. Paste the client secret and the refresh token, joined by a colon:
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¶
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 answerAPI_RULE_DENIEDbefore anything is sent. - It cannot read a native Google Doc. A Doc, Sheet or Slide has no bytes of
its own;
getFileContentreads 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.