How to Use Ephemeral API Keys in Building Blocks
This guide explains how to configure ephemeral API keys for building blocks. Ephemeral API keys allow your building blocks to interact with the meshStack API during their execution, enabling advanced automation patterns like creating nested building blocks, managing tenants, or updating other meshObjects, all without requiring admin permissions.
Challenge
You want to create a building block that provisions infrastructure and also needs to interact with meshStack during its execution. For example, your building block might need to:
- Create additional building blocks
- Update project or tenant tags
- Query workspace information
- Create tenants as part of a complex provisioning workflow
Traditionally, this would require manually managing API credentials and giving the building block broad admin access to the required resources. Ephemeral API keys solve this by providing short-lived, automatically managed credentials scoped to only the consuming workspace and the permissions your building block actually needs.
Prerequisites
- Admin permissions or workspace manager/owner permissions on the workspace that owns the building block definition
- A building block definition using one of the supported implementation types:
- OpenTofu
- GitHub Actions
- GitLab CI/CD
- Azure DevOps Pipelines
- Understanding of which meshStack API permissions your building block needs
Step-by-Step Guide
Step 1: Identify Required Permissions
Before configuring ephemeral API keys, identify which meshStack API permissions your building block needs. Common use cases include:
| Use Case | Permissions Needed |
|---|---|
| Create nested building blocks | Building Block (write), Building Block Definition (read) |
| Read workspace information | Workspace (read) |
| Manage projects | Project (read, write, delete) |
| Manage tenants | Tenant (read, write, delete) |
| Read event logs | Event Log (read) |
Only select the permissions your building block actually needs. The ephemeral API key is scoped to the workspace where the building block is provisioned, so you don't need to worry about cross-workspace access.
Step 2: Configure Permissions on the Building Block Definition
- Navigate to Platform Builder > Building Blocks > Definitions
- Select your building block definition (or create a new one)
- If editing an existing definition, click Create draft to start a new version
- Go to the Implementation tab
- Scroll to the Ephemeral API Keys section
- Select the required permissions from the dropdown
The UI shows a grouped list of available permissions organized by resource type (e.g., Building Block, Project, Tenant). Select all permissions your building block requires.
Step 3: Save and Release the Definition
After configuring permissions, save the building block definition version
meshStack automatically adds two system-generated inputs to your building block definition:
MESHSTACK_ENDPOINT: The meshStack API URLMESHSTACK_API_TOKEN: A placeholder that will be replaced with the actual token at runtime
You don't need to manually create these inputs. They appear automatically when you configure permissions. For OpenTofu building blocks, these inputs are provided as environment variables that the meshStack Terraform provider automatically uses for authentication.
When you have successfully tested your new building block definition, click Release to publish the new version.
Step 4: Use the API Token in Your Building Block Code
OpenTofu Building Blocks
For OpenTofu building blocks, the meshStack Terraform provider automatically uses the MESHSTACK_API_TOKEN and MESHSTACK_ENDPOINT environment variables. No additional configuration is needed:
terraform {
required_providers {
meshstack = {
source = "meshcloud/meshstack"
version = ">= 0.17.3"
}
}
}
# Provider automatically authenticates using MESHSTACK_API_TOKEN
provider "meshstack" {}
# Example: Create a nested building block
resource "meshstack_building_block_v2" "example_workspace" {
spec = {
building_block_definition_version_ref = {
uuid = "00000000-0000-0000-0000-000000000000" # Replace with actual definition version UUID
}
display_name = "my-building-block"
target_ref = {
kind = "meshWorkspace"
identifier = "my-workspace-identifier" # Replace with actual workspace identifier
}
inputs = {
name = { value_string = "my-name" }
size = { value_int = 16 }
}
}
}
GitHub Actions
For GitHub Actions building blocks, the API token is provided as a workflow input. Your workflow must declare the input in the workflow_dispatch trigger:
If your GitHub Actions building block uses asynchronous execution mode, you'll also receive MESHSTACK_RUN_URL and MESHSTACK_RUN_TOKEN as workflow inputs. These allow your workflow to report status updates back to meshStack. See GitHub Actions Integration for more details.
name: Building Block with API Access
on:
workflow_dispatch:
inputs:
buildingBlockRunUrl:
description: "Building Block Run Url"
required: true
MESHSTACK_API_TOKEN:
description: "meshStack API token"
required: true
type: string
MESHSTACK_ENDPOINT:
description: "meshStack API endpoint"
required: true
type: string
MESHSTACK_RUN_TOKEN:
description: "meshStack Run token"
required: true
type: string
jobs:
apply:
runs-on: ubuntu-latest
steps:
- name: Register Building Block Run Source
run: |
curl -X POST "${{ inputs.buildingBlockRunUrl }}/status/source" \
-H "Content-Type: application/vnd.meshcloud.api.meshbuildingblockrun.v1.hal+json" \
-H "Accept: application/vnd.meshcloud.api.meshbuildingblockrun.v1.hal+json" \
-H "Authorization: Bearer ${{ inputs.MESHSTACK_RUN_TOKEN }}" \
-d '{
"source": {
"id": "github"
},
"steps": [{
"id": "step1",
"displayName": "Execute",
"status": "IN_PROGRESS"
}]
}'
- name: Call meshStack API
run: |
curl -X GET "${{ inputs.MESHSTACK_ENDPOINT }}/api/meshobjects/meshprojects" \
-H "Authorization: Bearer ${{ inputs.MESHSTACK_API_TOKEN }}" \
-H "Accept: application/vnd.meshcloud.api.meshproject.v2.hal+json"
- name: Update Building Block Run Status to Succeeded
if: success()
run: |
curl -X PATCH "${{ inputs.buildingBlockRunUrl }}/status/source/github" \
-H "Content-Type: application/vnd.meshcloud.api.meshbuildingblockrun.v1.hal+json" \
-H "Accept: application/vnd.meshcloud.api.meshbuildingblockrun.v1.hal+json" \
-H "Authorization: Bearer ${{ inputs.MESHSTACK_RUN_TOKEN }}" \
-d '{
"status": "SUCCEEDED",
"steps": [{
"id": "step1",
"status": "SUCCEEDED"
}]
}'
- name: Update Building Block Run Status to Failed
if: failure()
run: |
curl -X PATCH "${{ inputs.buildingBlockRunUrl }}/status/source/github" \
-H "Content-Type: application/vnd.meshcloud.api.meshbuildingblockrun.v1.hal+json" \
-H "Accept: application/vnd.meshcloud.api.meshbuildingblockrun.v1.hal+json" \
-H "Authorization: Bearer ${{ inputs.MESHSTACK_RUN_TOKEN }}" \
-d '{
"status": "FAILED",
"steps": [{
"id": "step1",
"status": "FAILED"
}]
}'
GitLab CI/CD
For pipeline-based building blocks, access the token via environment variables:
# GitLab CI/CD example
my_job:
script:
- |
curl -X GET "${MESHSTACK_ENDPOINT}/api/meshobjects/meshprojects" \
-H "Authorization: Bearer ${MESHSTACK_API_TOKEN}" \
-H "Accept: application/vnd.meshcloud.api.meshproject.v3.hal+json"
Step 5: Verify Permissions in the Marketplace
After releasing the building block definition, verify that users see the correct permissions:
- Navigate to the marketplace
- Find your building block definition
- Check the Permissions section
Users see a list of permissions the building block will receive on their workspace. This transparency helps users make informed decisions before adding the building block.
Understanding API Key Lifecycle
Ephemeral API keys have a defined lifecycle:
- Creation: When a building block run starts, meshStack creates an ephemeral API key with the configured permissions, scoped to the consuming workspace
- Usage: The API key is valid during the building block run execution
- Deletion: The API key is automatically deleted when:
- The run reaches a terminal state (succeeded or failed), OR
- 6 hours have elapsed (maximum lifetime)
This lifecycle ensures credentials are short-lived and automatically cleaned up, reducing security risks.
Handling Privilege Escalation
If your building block creates nested building blocks that also have permission requirements, meshStack enforces privilege escalation prevention:
- A nested building block can only have permissions that are a subset of (or equal to) the parent building block's permissions
- If a nested building block requests more permissions than the parent has, the creation fails with an error
This ensures building blocks cannot grant themselves elevated access through nested automation.
Troubleshooting
API Token Not Working
- Verify the building block run is still active (tokens expire when runs complete)
- Check that the required permissions are configured on the definition
- Ensure you're using the token in the correct workspace context
Missing MESHSTACK_API_TOKEN Input
- Permissions must be configured on the building block definition version
- Save the building block definition after adding permissions
- The system inputs are auto-generated only when permissions are configured
Nested Building Block Creation Fails
- Check if the nested definition requires more permissions than the parent has
- Review the error message for details about which permissions are missing
- Ensure the parent building block has all permissions the nested building block needs