Create a principal that can read one mailbox, issue its credential, and rotate that credential through the IAM API. For principal, permission, and resource-binding concepts, see Nylas IAM.
Before you begin
Section titled “Before you begin”IAM management endpoints require an IAM credential whose active principal has an Organization resource binding and the required management permissions. Existing application API keys (including legacy API keys) and provider OAuth tokens can’t authorize these endpoints.
If you already have an active, unexpired IAM credential with these permissions, you can use it. Otherwise, create your first management credential in the Dashboard before making API requests.
Create a management credential in the Dashboard
Section titled “Create a management credential in the Dashboard”In the Nylas Dashboard:
- Open your organization’s Nylas IAM page and create a principal with an Organization resource binding.
- Assign the IAM Admin system role (
role_system_iam_admin). - Open the Credentials tab and create a credential for that active principal. Choose an expiration and store the secret securely.
- Load the secret into your server as
NYLAS_IAM_ADMIN_KEY. Keep it separate from the scoped key you create for your workload.
Send the credential’s secret as Authorization: Bearer <NYLAS_IAM_ADMIN_KEY>. Requests act within that credential’s organization.
Use https://api.us.nylas.com for the U.S. region or https://api.eu.nylas.com for the E.U. region. Use the same region as the application that owns a Grant, Workspace, or Application binding.
Choose management permissions
Section titled “Choose management permissions”The IAM Admin role lets you manage principals and credentials. For read-only access, use IAM Auditor (role_system_iam_auditor). Both require an Organization resource binding.
For narrower automation, assign only the permissions you need through a custom role or direct assignments. Each operation in the principals and credentials references lists its required permission. Manage custom roles in the Dashboard.
Provision a workload
Section titled “Provision a workload”Use your management credential for both creation requests. The workload will use the separate credential you create for it.
Create a scoped principal
Section titled “Create a scoped principal”This example creates a mailbox reader bound to one grant. Set NYLAS_GRANT_ID to a grant in your organization. In the curl request, replace <NYLAS_GRANT_ID> in the JSON body with that ID.
curl --request POST \ --url "https://api.us.nylas.com/v3/iam/principals" \ --header "Authorization: Bearer $NYLAS_IAM_ADMIN_KEY" \ --header "Content-Type: application/json" \ --data '{"name": "Support mailbox reader", "roles": ["role_system_messages_reader"], "resource_binding": {"type": "grant", "id": "<NYLAS_GRANT_ID>"}}'const requiredEnvironment = (name) => { const value = process.env[name]?.trim(); if (!value) throw new Error(`Set ${name} before running this example`); return value;};const adminKey = requiredEnvironment("NYLAS_IAM_ADMIN_KEY");// Node.js 22+: direct HTTP, without SDK-specific IAM methods.const response = await fetch("https://api.us.nylas.com/v3/iam/principals", { method: "POST", signal: AbortSignal.timeout(30000), headers: { Authorization: `Bearer ${adminKey}`, "Content-Type": "application/json", }, body: JSON.stringify({ name: "Support mailbox reader", roles: ["role_system_messages_reader"], resource_binding: { type: "grant", id: requiredEnvironment("NYLAS_GRANT_ID"), }, }),});if (!response.ok) throw new Error(`Principal creation failed (${response.status})`);const { data: principal } = await response.json();console.log(principal.id);import jsonimport osfrom urllib.request import Request, urlopen
request = Request( "https://api.us.nylas.com/v3/iam/principals", method="POST", headers={ "Authorization": f"Bearer {os.environ['NYLAS_IAM_ADMIN_KEY']}", "Content-Type": "application/json", }, data=json.dumps({ "name": "Support mailbox reader", "roles": ["role_system_messages_reader"], "resource_binding": {"type": "grant", "id": os.environ["NYLAS_GRANT_ID"]}, }).encode(),)with urlopen(request, timeout=30) as response: principal = json.load(response)["data"]print(principal["id"])Save the returned data.id as NYLAS_PRINCIPAL_ID. This principal has messages.read permission for the bound grant. For other bindings, roles, and field requirements, see Create IAM principal.
Create an IAM credential
Section titled “Create an IAM credential”Set NYLAS_PRINCIPAL_ID to the principal ID returned above. Create an api_key credential with a 90-day lifetime:
# Store the returned secret securely. Do not capture it in shared logs.EXPIRES_AT=$(python3 -c "import time; print(int(time.time()) + 90 * 86400)")
curl --request POST \ --url "https://api.us.nylas.com/v3/iam/principals/${NYLAS_PRINCIPAL_ID}/credentials" \ --header "Authorization: Bearer $NYLAS_IAM_ADMIN_KEY" \ --header "Content-Type: application/json" \ --data "{\"name\": \"Support worker key\", \"expires_at\": ${EXPIRES_AT}}"const requiredEnvironment = (name) => { const value = process.env[name]?.trim(); if (!value) throw new Error(`Set ${name} before running this example`); return value;};const adminKey = requiredEnvironment("NYLAS_IAM_ADMIN_KEY");// Store data.secret in your secrets service. Never log the response.const principalId = encodeURIComponent( requiredEnvironment("NYLAS_PRINCIPAL_ID"),);const response = await fetch( `https://api.us.nylas.com/v3/iam/principals/${principalId}/credentials`, { method: "POST", signal: AbortSignal.timeout(30000), headers: { Authorization: `Bearer ${adminKey}`, "Content-Type": "application/json", }, body: JSON.stringify({ name: "Support worker key", expires_at: Math.floor(Date.now() / 1000) + 90 * 86400, }), },);if (!response.ok) throw new Error(`Credential creation failed (${response.status})`);const { data: credential } = await response.json();// Pass credential.secret directly to your secrets-service client here.// Save credential.id so you can rotate or revoke this key later.import jsonimport osimport timefrom urllib.parse import quotefrom urllib.request import Request, urlopen
principal_id = quote(os.environ["NYLAS_PRINCIPAL_ID"], safe="")request = Request( f"https://api.us.nylas.com/v3/iam/principals/{principal_id}/credentials", method="POST", headers={ "Authorization": f"Bearer {os.environ['NYLAS_IAM_ADMIN_KEY']}", "Content-Type": "application/json", }, data=json.dumps({ "name": "Support worker key", "expires_at": int(time.time()) + 90 * 86400, }).encode(),)with urlopen(request, timeout=30) as response: credential = json.load(response)["data"]# Pass credential["secret"] directly to your secrets-service client here.# Save credential["id"] for rotation or revocation. Never log the response.Store data.secret in your secrets service immediately. Nylas returns it only once, so don’t log the response. Save data.id for rotation or revocation.
The credential inherits its principal’s access. For expiration requirements and response fields, see Create IAM credential.
Use the workload credential
Section titled “Use the workload credential”Load the new secret as NYLAS_IAM_API_KEY in the workload’s server. It can now read messages from the bound grant:
curl --request GET \ --url "https://api.us.nylas.com/v3/grants/$NYLAS_GRANT_ID/messages" \ --header "Authorization: Bearer $NYLAS_IAM_API_KEY"Keep the organization management key out of this workload. Provider OAuth scopes still constrain what Nylas can do with the connected account; IAM permissions don’t replace them.
Manage existing principals and credentials
Section titled “Manage existing principals and credentials”Use the organization management credential for these operations. Changes to a principal affect all credentials attached to it.
List and paginate principals or credentials
Section titled “List and paginate principals or credentials”Use List IAM principals or List IAM credentials. If the response includes next_cursor, pass it as page_token on the next request. Stop when next_cursor is absent. The references cover filters and page sizes.
Update a principal’s access
Section titled “Update a principal’s access”Use Update IAM principal to change the workload’s access. Supplied fields replace their current values; omitted fields stay unchanged. For example, {"direct_permissions": ["messages.read"]} replaces the entire direct-permission set.
Disable a principal to stop all of its credentials from authenticating. Delete it only when you want to permanently remove the principal and every attached credential. See Delete IAM principal.
Rotate or revoke credentials
Section titled “Rotate or revoke credentials”To rotate a key without downtime:
- Create a replacement credential on the same principal.
- Store and deploy the new secret.
- Verify the workload can make its intended requests.
- Delete the old credential.
To stop access immediately, disable the credential. Deleting a credential is permanent.
Understand principal and credential limits
Section titled “Understand principal and credential limits”Reserve credential capacity for rotation so you can deploy a replacement before deleting the old credential. For quota formulas, counting rules, and examples, see the IAM principals reference.
Troubleshoot IAM management requests
Section titled “Troubleshoot IAM management requests”For authentication or permission failures, check that your management credential is active and unexpired, its principal is active, and the principal has an Organization binding and the operation’s required permission. Use the response’s request_id to inspect IAM activity. Each operation’s reference lists its errors.
If credential creation times out, list the principal’s credentials before retrying. Nylas might have created a credential even if you didn’t receive its secret. Delete any unusable credential before creating a replacement.
Use IAM keys with MCP
Section titled “Use IAM keys with MCP”To give an MCP agent access to this mailbox, load the workload credential’s secret as NYLAS_API_KEY and follow the MCP client setup instructions. Keep the management credential in your provisioning service.
Use the MCP endpoint for your application’s region and the bound grant ID. Verify that the agent can read messages. After rotation, load the replacement secret and restart the client before deleting the old credential.
What’s next
Section titled “What’s next”- IAM principals API reference
- IAM credentials API reference
- Application API-key management for the separate application-wide key API
- Security best practices for credential storage and least privilege