DDroomwork Developers

Core concepts

Authentication

Two ways to prove who you are, and the one thing neither of them asks you for.

An API key, for a server that holds one

The simplest way in. Create an account, take the key, and send it as a header.

Droomwork-Api-Key: dw_test_...

The same key is also accepted after Bearer in the Authorization header, which is where an OAuth client already puts its token and what our client libraries send. One credential, presented two ways; use whichever your HTTP layer makes easier.

Authorization: Bearer dw_test_...

You see the key once, when it's issued, and never again. No endpoint returns it: a key we could hand back is a key anybody who reaches your account could hand themselves. If you lose one, make another and revoke the old one.

We keep only a digest of it, never the key itself.

A token, for a client that can hold a secret

The client credentials grant, for when you'd rather not put a long lived key on every request.

POST /v1/oauth/token
Content-Type: application/json

{ "grant_type": "client_credentials",
  "client_id": "...",
  "client_secret": "...",
  "scope": "run:read run:write" }

The token carries your organisation and your scopes. Send it as Authorization: Bearer. It's short lived, so a leaked one stops working on its own.

An unknown client and a wrong secret get the same answer, so you can't tell one from the other by the response.

The organisation is never something you send

This is the rule underneath both.

Your organisation comes from the credential you present and from nothing else in the request. No endpoint takes an organisation identifier as an input to scope by. A request that named one could name somebody else's.

Scopes

Each of the eight modules has three: read, write and approve. run:read lets you look at payroll. run:approve lets you approve a run. The difference between those two is the difference between looking at money and moving it.

A safe method needs read. A path ending in /approve needs approve. Everything else needs write. Without the scope you get forbidden, and the message names the scope you were missing.

Your first key carries every named scope in the sandbox, so nothing you try first fails for the wrong reason. Later keys can carry fewer. You can't be issued a wildcard.