> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sensorup.com/llms.txt
> Use this file to discover all available pages before exploring further.

# GraphQL API Authentication

> Learn how to authenticate with the SensorUp GraphQL API using sessions, API keys, and AWS credentials.

# Authentication

The SensorUp GraphQL API supports multiple authentication methods depending on your use case and environment.

## Authentication Methods

| Method                | Use Case                         | Lifetime                                           | MFA Support      |
| --------------------- | -------------------------------- | -------------------------------------------------- | ---------------- |
| **Session-based**     | Interactive web applications     | 7-30 days idle, 30-365 days max (varies by client) | Yes              |
| **API Keys**          | Machine-to-machine, integrations | 60 days idle, 365 days max                         | No               |
| **Federated Sign-in** | SSO integration                  | Same as session-based                              | Via SSO provider |

All authentication methods use the same session ID mechanism - either via the `sensorup_sessionid` cookie (browser) or `x-sensorup-sessionid` header (API clients).

## Session-Based Authentication

Session-based authentication is the primary method for interactive applications where users log in with username and password.

### Sign In

```graphql theme={null}
mutation SignIn($input: AuthSignInInput!) {
  signIn(input: $input) {
    session {
      username
      authenticated
      expiresAt
      expiresAtHard
      userGroup
      challengeName
    }
    correlationId
    errors {
      message
      type
    }
  }
}
```

**Variables:**

```json theme={null}
{
  "input": {
    "loginUsername": "user@example.com",
    "password": "your-password",
    "clientApplicationType": "EXPLORER"
  }
}
```

### Session Response

```json theme={null}
{
  "data": {
    "signIn": {
      "session": {
        "username": "user@example.com",
        "authenticated": true,
        "expiresAt": "2025-11-05T18:00:00Z",
        "expiresAtHard": "2025-11-06T10:00:00Z",
        "userGroup": "your-tenant-id",
        "challengeName": null
      },
      "correlationId": "abc-123",
      "errors": []
    }
  }
}
```

### Checking Current Session

```graphql theme={null}
query GetSession {
  session {
    username
    authenticated
    expiresAt
    userGroup
    lastAuthenticatedAt
  }
}
```

### Sign Out

```graphql theme={null}
mutation SignOut {
  signOut {
    session {
      authenticated
    }
    correlationId
    errors {
      message
      type
    }
  }
}
```

### Using Your Session

After successful sign-in, your session ID is used to authenticate subsequent API requests. There are two methods:

#### 1. Cookie Authentication (Browser/Web)

When you sign in through a web browser, the `sensorup_sessionid` cookie is automatically set and sent with each request:

```
Cookie: sensorup_sessionid=YOUR_SESSION_ID
```

This happens automatically - you don't need to manually set this cookie in browser applications.

#### 2. Header Authentication (Machine-to-Machine)

For API clients, mobile apps, and integrations, pass the session ID in the `x-sensorup-sessionid` header:

```bash theme={null}
curl -X POST https://customer-demo.sensorup.com/api/graphql \
  -H "Content-Type: application/json" \
  -H "x-sensorup-sessionid: YOUR_SESSION_ID" \
  -d '{"query":"{ session { username authenticated } }"}'
```

**Using with HTTP clients:**

```javascript theme={null}
// JavaScript/Node.js
fetch('https://customer-demo.sensorup.com/api/graphql', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-sensorup-sessionid': sessionId
  },
  body: JSON.stringify({ query: '{ session { username } }' })
})
```

```python theme={null}
# Python
import requests

response = requests.post(
    'https://customer-demo.sensorup.com/api/graphql',
    headers={
        'Content-Type': 'application/json',
        'x-sensorup-sessionid': session_id
    },
    json={'query': '{ session { username } }'}
)
```

## Multi-Factor Authentication (MFA)

When MFA is required, the sign-in mutation returns a `challengeName`:

### MFA Challenge Response

```json theme={null}
{
  "session": {
    "username": "user@example.com",
    "authenticated": false,
    "challengeName": "SMS_MFA",
    "challengeParam": {}
  }
}
```

### Challenge Types

| Challenge               | Description             |
| ----------------------- | ----------------------- |
| `SMS_MFA`               | SMS-based one-time code |
| `SOFTWARE_TOKEN_MFA`    | TOTP authenticator app  |
| `MFA_SETUP`             | MFA setup required      |
| `NEW_PASSWORD_REQUIRED` | Password reset required |

### Completing MFA Challenge

```graphql theme={null}
mutation ConfirmSignIn($input: AuthConfirmSignInInput!) {
  confirmSignIn(input: $input) {
    session {
      username
      authenticated
      expiresAt
    }
    correlationId
    errors {
      message
      type
    }
  }
}
```

**Variables:**

```json theme={null}
{
  "input": {
    "code": "123456",
    "mfaType": "SMS_MFA"
  }
}
```

## API Key Authentication

API keys are designed for machine-to-machine communication and integration scenarios. API keys generate sessions just like user logins, but with longer lifetimes.

### Creating an API Key

```graphql theme={null}
mutation CreateAPIKey($input: AuthCreateAPIKeyInput!) {
  createAPIKey(input: $input) {
    apiKey {
      apiKeyId
      apiKeySessionId
      username
      authenticated
      expiresAt
      userGroup
    }
    correlationId
    errors {
      message
      type
    }
  }
}
```

**Variables:**

```json theme={null}
{
  "input": {
    "apiKeyId": "my-integration-key",
    "userGroup": "your-tenant-id"
  }
}
```

The response includes an `apiKeySessionId` which is the session ID you'll use for authentication.

<Callout type="warning">
  API keys provide full access to the API with the same permissions as the user who created them. Store them securely and rotate them regularly.
</Callout>

### Using API Keys

Use the API key session ID in the `x-sensorup-sessionid` header (same as regular sessions):

```bash theme={null}
curl -X POST https://customer-demo.sensorup.com/api/graphql \
  -H "Content-Type: application/json" \
  -H "x-sensorup-sessionid: YOUR_API_KEY_SESSION_ID" \
  -d '{"query":"{ session { username } }"}'
```

**Integration Example:**

```javascript theme={null}
// Store the API key session ID securely
const apiKeySessionId = process.env.SENSORUP_API_KEY_SESSION_ID

// Use in requests
const response = await fetch('https://customer-demo.sensorup.com/api/graphql', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-sensorup-sessionid': apiKeySessionId
  },
  body: JSON.stringify({ query: '{ session { username } }' })
})
```

## AWS Credentials

For accessing AWS services (S3, etc.), you can obtain temporary AWS credentials:

### Getting AWS Credentials

```graphql theme={null}
query GetCredentials($group: String) {
  credentials(group: $group) {
    accessKeyId
    secretAccessKey
    sessionToken
    expiration
  }
}
```

**Response:**

```json theme={null}
{
  "data": {
    "credentials": {
      "accessKeyId": "ASIA...",
      "secretAccessKey": "...",
      "sessionToken": "...",
      "expiration": "2025-11-05T18:00:00Z"
    }
  }
}
```

### Using AWS Credentials

```javascript theme={null}
import AWS from 'aws-sdk'

// Configure AWS SDK with credentials from GraphQL
AWS.config.credentials = new AWS.Credentials({
  accessKeyId: credentials.accessKeyId,
  secretAccessKey: credentials.secretAccessKey,
  sessionToken: credentials.sessionToken
})

// Use AWS services
const s3 = new AWS.S3()
```

## Federated Sign-In (SSO)

For organizations using SSO, you can authenticate with Cognito tokens:

```graphql theme={null}
mutation FederatedSignIn($input: AuthFederatedSignInInput!) {
  federatedSignIn(input: $input) {
    session {
      username
      authenticated
      expiresAt
      userGroup
    }
    correlationId
    errors {
      message
      type
    }
  }
}
```

**Variables:**

```json theme={null}
{
  "input": {
    "cognitoIdToken": "your-id-token",
    "clientApplicationType": "EXPLORER"
  }
}
```

<Callout type="info">
  SSO configuration is tenant-specific. Contact your SensorUp account team for SSO setup and configuration.
</Callout>

## Session Management

### Session Expiration

Sessions have two expiration times:

* **Soft Expiry (Idle Timeout)**: Session extends with activity up to this limit
* **Hard Expiry (Maximum Lifetime)**: Absolute maximum session duration - requires re-authentication after this time

Session lifetimes vary by client application type:

| Client Application Type | Hard Expiry (Max Lifetime) | Soft Expiry (Idle Timeout) |
| ----------------------- | -------------------------- | -------------------------- |
| **Explorer** (Web)      | 30 days                    | 7 days                     |
| **SensorHub Android**   | 365 days                   | 60 days                    |
| **SensorHub iOS**       | 365 days                   | 60 days                    |
| **API Key**             | 365 days                   | 60 days                    |

**How it works:**

* If you're actively using the API, your session stays valid until the hard expiry time
* If you're inactive for longer than the soft expiry (idle timeout), the session expires
* After hard expiry, you must sign in again regardless of activity
* The `expiresAt` field in the session response reflects the current soft expiry time
* The `expiresAtHard` field shows the absolute maximum session lifetime

### Switching User Groups

If your user has access to multiple tenant groups:

```graphql theme={null}
mutation SetUserGroup($input: AuthSetSessionUserGroupInput!) {
  setSessionUserGroup(input: $input) {
    session {
      userGroup
    }
    correlationId
    errors {
      message
      type
    }
  }
}
```

**Variables:**

```json theme={null}
{
  "input": {
    "userGroup": "different-tenant-id"
  }
}
```

### Re-authentication

For sensitive operations, you may need to re-authenticate:

```graphql theme={null}
mutation Reauthenticate($input: ReauthenticationInput!) {
  reauthenticate(input: $input) {
    session {
      username
      authenticated
      lastAuthenticatedAt
    }
    correlationId
    errors {
      message
      type
    }
  }
}
```

**Variables:**

```json theme={null}
{
  "input": {
    "password": "your-password"
  }
}
```

## Device Management

Track and manage authenticated devices:

### Listing Devices

```graphql theme={null}
query GetUserDevices($userId: ID!) {
  user(id: $userId) {
    devices {
      deviceKey
      name
      remembered
      createdAt
      lastSignedInAt
      lastIpAddress
    }
  }
}
```

### Forgetting Devices

```graphql theme={null}
mutation ForgetDevices($input: AuthForgetSpecificDevicesInput!) {
  forgetDevices(input: $input) {
    session {
      username
    }
    correlationId
    errors {
      message
      type
    }
  }
}
```

**Variables:**

```json theme={null}
{
  "input": {
    "deviceKeys": ["device-key-1", "device-key-2"]
  }
}
```

## Password Management

### Forgot Password

```graphql theme={null}
mutation ForgotPassword($input: AuthForgotPasswordInput!) {
  forgotPassword(input: $input) {
    correlationId
    errors {
      message
      type
    }
  }
}
```

**Variables:**

```json theme={null}
{
  "input": {
    "loginUsername": "user@example.com"
  }
}
```

### Reset Password

```graphql theme={null}
mutation ForgotPasswordSubmit($input: AuthForgotPasswordSubmitInput!) {
  forgotPasswordSubmit(input: $input) {
    session {
      username
      authenticated
    }
    correlationId
    errors {
      message
      type
    }
  }
}
```

**Variables:**

```json theme={null}
{
  "input": {
    "loginUsername": "user@example.com",
    "confirmationCode": "123456",
    "password": "new-password"
  }
}
```

## Authentication Configuration

Query authentication configuration for your environment:

```graphql theme={null}
query GetAuthConfig {
  config {
    auth {
      loginEnabled
      ssoEnabled
      ssoUrl
    }
  }
}
```

## Best Practices

1. **Use sessions for interactive applications**: Session-based auth with MFA provides the best security for user-facing applications

2. **Use API keys for integrations**: Machine-to-machine communication should use API keys with appropriate scoping

3. **Rotate credentials regularly**: Implement key rotation policies for long-lived API keys

4. **Handle session expiration gracefully**: Check `expiresAt` and refresh or re-authenticate before expiration

5. **Store credentials securely**: Never commit credentials to version control; use environment variables or secret management systems

6. **Monitor authentication events**: Track authentication failures and unusual patterns

## Next Steps

* **[Quickstart Guide](./quickstart)** - Make your first authenticated query
* **[Common Patterns](./common-patterns)** - Learn about pagination and filtering
* **[Domain Guides](./guides/cam-assets)** - Explore specific API capabilities
