Least privilege customer access with Indent
Learn how to submit your first approval request using Next.js and Indent Approval Kit.
Prerequisites
- Node.js v18+
- Indent API key
1. Install
Install the Indent JavaScript SDK and Approval Kit:
npm install --save @indent/api @indent/approvals
2. Get your API key
First, you'll need an Indent space and API token which you can find here: indent.com/api-keys
- Current User
- Sign in to get API key
- Can take actions on your behalf
- Appears in audit log as you
- Indent Space
- Access Token
- Note: this token is short lived and will expire soon
- .env
INDENT_SPACE= INDENT_API_TOKEN=************************************************************************************
The INDENT_SPACE
is the Indent account you want to use for requests and an INDENT_API_TOKEN
which is used for authentication. There are two kinds of API tokens: short-lived user access tokens and long-lived service account tokens. Read more about API authentication.
3. Upload customers to Indent
Before we can request access to customers, we'll need to load them into Indent. We'll first list the customers from our database (abstracted as ./db
) and use the Indent JavaScript SDK to upload after transforming into the Indent Resource Format:
import { IndentAPI } from '@indent/api'
import db from './db'
const client = new IndentAPI()
async function upload() {
const customers = await db.customers.list()
await client.resource.bulkUpdate({
resources: customers.map(c => ({
kind: 'customer',
id: c.id,
displayName: c.name,
labels: { plan: c.plan }
}))
})
}
upload()
Either on a recurring schedule or when customers are created or updated, we'll want to upload them to Indent. In this case, we'll just run this script:
node upload.js
4. Add await approval
Now that we have customers in Indent, we can request access to them:
import { approval, getErrorKind } from '@indent/approvals'
import { getCurrentUser } from './auth'
async function requestCustomerAccess(ctx, customerId) {
try {
const user = await getCurrentUser(ctx)
await approval({
petitioners: [{ kind: 'user', id: user.id, email: user.email }],
resources: [{ kind: 'customer', id: customerId }]
})
return { ok: true }
} catch (err) {
switch (getErrorKind(err)) {
case 'waiting':
// Once granted, it will auto-approve next time
return { ok: false, status: 'waiting' }
case 'denied':
// Denied by reviewer or policy
return { ok: false, status: 'denied' }
default:
console.error(err)
return { ok: false, status: 'unknown' }
}
}
}
Now, when a member of staff clicks "Request Access" in the admin portal, the API will request access on their behalf and wait for approval.