Skip to content
Developer Preview — APIs and language features may change before 1.0

Authentication

mashin supports multiple authentication methods. Social login for individual users, enterprise SSO for organizations, surface auth for per-machine access control, and invites for sharing.

Sign in with GitHub, Google, Microsoft, or Apple. These are configured at the computer level.

Set the provider credentials in your environment or runtime.exs:

Terminal window
# GitHub
GITHUB_CLIENT_ID=your_client_id
GITHUB_CLIENT_SECRET=your_client_secret
GITHUB_REDIRECT_URI=https://your-computer.mashin.cloud/auth/user/github/callback
# Google
GOOGLE_CLIENT_ID=your_client_id
GOOGLE_CLIENT_SECRET=your_client_secret
GOOGLE_REDIRECT_URI=https://your-computer.mashin.cloud/auth/user/google/callback
# Microsoft
MICROSOFT_CLIENT_ID=your_client_id
MICROSOFT_CLIENT_SECRET=your_client_secret
MICROSOFT_REDIRECT_URI=https://your-computer.mashin.cloud/auth/user/microsoft/callback
# Apple
APPLE_CLIENT_ID=your_client_id
APPLE_TEAM_ID=your_team_id
APPLE_PRIVATE_KEY_ID=your_key_id
APPLE_PRIVATE_KEY_PATH=/path/to/AuthKey.p8
APPLE_REDIRECT_URI=https://your-computer.mashin.cloud/auth/user/apple/callback

The login page only shows buttons for providers that have credentials configured. If you only set up GitHub, only the GitHub button appears.

Email-based sign-in for existing users. The user enters their email, receives a link, clicks it, and is signed in. No password needed.

Magic link is sign-in only, not registration. New users must sign in via a social provider to create their account. This prevents spam.

Connect your organization’s Microsoft Entra ID (formerly Azure AD) for single sign-on. Users sign in with their corporate Microsoft account.

  1. Go to Azure Portal > Microsoft Entra ID > App registrations > New registration
  2. Name: “mashin” (or your preferred name)
  3. Supported account types: “Accounts in this organizational directory only” (single tenant)
  4. Redirect URI: https://your-computer.mashin.cloud/auth/oidc/callback (Web platform)
  5. Click Register

After registration:

  • Copy the Application (client) ID
  • Copy the Directory (tenant) ID
  • Go to Certificates & secrets > New client secret > copy the Value
  1. Go to API permissions > Add a permission > Microsoft Graph > Delegated permissions
  2. Add: openid, email, profile, User.Read
  3. Click “Grant admin consent” (requires admin)

Option A: Environment variables (computer-wide)

Terminal window
MASHIN_OIDC_ISSUER=https://login.microsoftonline.com/{tenant-id}/v2.0
MASHIN_OIDC_CLIENT_ID=your-application-client-id
MASHIN_OIDC_CLIENT_SECRET=your-client-secret-value

Option B: Per-organization via API (Koda-configurable)

Terminal window
# Create an SSO connection for your organization
curl -X POST https://your-computer.mashin.cloud/api/sso-connections \
-H "Authorization: Bearer msk_your_key" \
-H "Content-Type: application/json" \
-d '{
"name": "Acme Corp Entra ID",
"provider": "azure_ad",
"auth_method": "direct_oidc",
"oidc_issuer": "https://login.microsoftonline.com/{tenant-id}/v2.0",
"oidc_client_id": "your-client-id",
"oidc_client_secret": "your-client-secret",
"domains": ["acme.com"],
"enforce_sso": true
}'

When enforce_sso is true, users with @acme.com emails are redirected to Entra ID automatically. They cannot sign in with social login.

Option C: Via Koda

Tell Koda: “Set up Microsoft Entra ID SSO for our organization. The tenant ID is abc-123, client ID is def-456.”

Koda creates the SSOConnection with the correct configuration.

Visit your computer’s login page. Users with matching email domains will see “Sign in with SSO” or be redirected automatically.

The same Direct OIDC flow works with any OIDC-compliant provider:

Provider Issuer URL format
Microsoft Entra ID https://login.microsoftonline.com/{tenant-id}/v2.0
Okta https://{your-domain}.okta.com
Google Workspace https://accounts.google.com
PingIdentity https://auth.pingone.com/{environment-id}/as
Auth0 https://{your-domain}.auth0.com/
Keycloak https://{host}/realms/{realm}
OneLogin https://{your-domain}.onelogin.com/oidc/2

Configure the issuer URL, client ID, and client secret. mashin discovers the authorization and token endpoints automatically from {issuer}/.well-known/openid-configuration.

Every machine surface (API, MCP, page, webhook) can declare authentication requirements in mashinTalk:

expresses
api
path: "/api/data"
auth: oauth, api_key
scopes: machines:run
allow: @acme.com, partner@example.com
page
title: "Dashboard"
auth: session
allow: @acme.com

See Surface authentication for full details.

Method How it works Best for
public No authentication Public APIs, landing pages
api_key Authorization: Bearer msk_... Machine-to-machine, CI/CD
oauth OAuth 2.1 bearer token (JWT) MCP clients, third-party apps
session Browser session cookie Human-facing pages
signature HMAC-SHA256 webhook signature Incoming webhooks

Restrict who can access a surface after authentication:

Pattern Matches
@acme.com Any user with an @acme.com email
[email protected] That specific email
@*.acme.com Any subdomain: eng.acme.com, sales.acme.com
client:oac2_xxx A specific OAuth client ID

On localhost in dev/test, surface auth is skipped. No OAuth setup needed for local development.

Invite users to access a deployed machine via email:

Terminal window
curl -X POST https://your-computer.mashin.cloud/api/deployments/{id}/auth/invite \
-H "Authorization: Bearer msk_your_key" \
-H "Content-Type: application/json" \
-d '{"email": "[email protected]"}'

The invitee receives a link. They sign in with a social provider (which creates their mashin account) and are redirected to the deployed machine. Their email is automatically added to the deployment’s allow list.

Every mashin computer is an OAuth 2.1 provider. External agents (Claude.ai, ChatGPT, Cursor) authenticate to your computer using standard OAuth.

  • Discovery: /.well-known/openid-configuration
  • Authorization code with PKCE (RFC 7636)
  • Dynamic client registration (RFC 7591)
  • Audience-bound tokens (RFC 8707)

See expresses reference for configuring OAuth scopes per surface.

Koda can manage authentication settings via natural language:

  • “Set up Entra ID SSO for our org”
  • “Add [email protected] to the dashboard allow list”
  • “Invite the sales team to the client portal”
  • “Show me who accessed the API today”
  • “Change the dashboard auth to require OAuth”

Koda reads the SSOConnection and DeployedMachine resources, modifies them via Ash actions, and the changes take effect immediately.

POST /api/sso-connections Create SSO connection
GET /api/sso-connections List connections
PUT /api/sso-connections/:id Update connection
DELETE /api/sso-connections/:id Delete connection
GET /api/deployments/:id/auth/surfaces Surface auth config
PUT /api/deployments/:id/auth/allow Update allow list
GET /api/deployments/:id/auth/api-keys List API keys
POST /api/deployments/:id/auth/api-keys Create API key
DELETE /api/deployments/:id/auth/api-keys/:k Revoke API key
POST /api/deployments/:id/auth/invite Send invite
GET /api/deployments/:id/auth/access-log Access events

Users manage their API keys and OAuth apps at /settings:

  • API Keys: create, list, revoke
  • OAuth Apps: register, list, delete (for third-party integrations)
  • Credentials: connect external services (GitHub, Google, etc.)

When embedding a mashin page in an external site, auth works the same way:

<!-- API key auth (simple, for trusted sites) -->
<mashin-page machine="dashboard" auth="api_key:msk_your_key"></mashin-page>
<!-- OAuth auth (secure, for public sites) -->
<mashin-page machine="dashboard" auth="oauth"></mashin-page>
<!-- Session auth (user must log in) -->
<mashin-page machine="dashboard" auth="session"></mashin-page>

The web component handles the auth flow. For OAuth, it opens a popup to the computer’s authorize endpoint. For session, it redirects to the login page. The auth token is stored in the component’s scope, not in the host page’s cookies.

The embed: config in mashinTalk controls which sites can embed:

expresses
page
auth: session
embed: "https://myapp.com", "https://staging.myapp.com"