Skip to content
Back to skills

Connection Schema Design

ASecurity

Connection profile and state schema design rules and core profile selection

  • 666 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 2, 2026
ai-agentsgobashnodeapidocumentation

Works with

  • cli
  • api

Security analysis

A100/100

Scanned September 2, 2026

npx -y skills add majiayu000/claude-skill-registry --skill connection-schema-design --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Connection Schema Design?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Connection Schema Design
[![Security: A β€” Skills Directory](https://www.skillsdirectory.com/api/skills/majiayu000-connection-schema-design-claude-skill-registry/badge)](https://www.skillsdirectory.com/skills/majiayu000-connection-schema-design-claude-skill-registry)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: connection-schema-design
description: Connection profile and state schema design rules and core profile selection
---

# Connection Profile & State Design Rules

**Rules for designing connectionProfile.yml and connectionState.yml schemas**

## 🚨 CRITICAL RULES

### Rule 1: Always Extend Core Profiles

**NEVER create custom profiles from scratch - ALWAYS extend core profiles**

```yaml
# ❌ WRONG - Custom profile
type: object
properties:
  apiKey:
    type: string

# βœ… CORRECT - Extend core profile
$ref: './node_modules/@auditmation/types-core/schema/tokenProfile.yml'
```

### Rule 2: connectionState MUST Extend baseConnectionState

**🚨 MANDATORY**: connectionState.yml MUST extend baseConnectionState.yml for expiresIn

```yaml
# βœ… CORRECT - Extends base with expiresIn
allOf:
  - $ref: './node_modules/@auditmation/types-core/schema/baseConnectionState.yml'
  - type: object
    properties:
      accessToken:
        type: string

# ❌ WRONG - Missing baseConnectionState
type: object
properties:
  accessToken:
    type: string
  # Missing expiresIn!
```

**WHY**: Server uses expiresIn to schedule automatic token refresh cronjobs

### Rule 3: expiresIn Must Be in Seconds

```yaml
# βœ… CORRECT
expiresIn:
  type: integer
  description: Token expiry time in SECONDS from now

# ❌ WRONG
expiresAt:
  type: string  # Don't use expiresAt, convert to expiresIn
```

**Calculation**: `expiresIn = Math.floor((expiresAt - now) / 1000)`

## Core Profile Selection

### Available Core Profiles

| Profile | When to Use | Contains |
|---------|-------------|----------|
| **tokenProfile.yml** | API Key, Bearer Token, PAT | token |
| **oauthClientProfile.yml** | OAuth2 Client Credentials | clientId, clientSecret |
| **oauthTokenProfile.yml** | OAuth2 with Refresh | clientId, clientSecret |
| **basicConnection.yml** | Username/Password, Email/Password | username, password |

**Path**: `./node_modules/@auditmation/types-core/schema/{profileName}.yml`

### Selection Decision Tree

```
@credential-manager provides authMethodType:

IF authMethodType == "bearer-token" OR "api-key"
  β†’ EXTEND tokenProfile.yml

IF authMethodType == "oauth2-client-credentials"
  β†’ EXTEND oauthClientProfile.yml

IF authMethodType == "oauth2-authorization-code"
  β†’ EXTEND oauthTokenProfile.yml

IF authMethodType == "basic-auth"
  β†’ EXTEND basicConnection.yml
```

## Available Core States

| State | When to Use | Contains |
|-------|-------------|----------|
| **tokenConnectionState.yml** | Simple token auth | accessToken + expiresIn |
| **oauthTokenState.yml** | OAuth with refresh | accessToken + refreshToken + expiresIn |

### State Selection

```
IF requiresRefresh == false
  β†’ EXTEND tokenConnectionState.yml

IF requiresRefresh == true
  β†’ EXTEND oauthTokenState.yml
```

## Common Patterns

### Pattern 1: Simple API Token

```yaml
# connectionProfile.yml
$ref: './node_modules/@auditmation/types-core/schema/tokenProfile.yml'

# connectionState.yml
$ref: './node_modules/@auditmation/types-core/schema/tokenConnectionState.yml'
```

### Pattern 2: OAuth Client Credentials

```yaml
# connectionProfile.yml
$ref: './node_modules/@auditmation/types-core/schema/oauthClientProfile.yml'

# connectionState.yml (no refresh)
$ref: './node_modules/@auditmation/types-core/schema/tokenConnectionState.yml'
```

### Pattern 3: OAuth with Refresh Token

```yaml
# connectionProfile.yml
$ref: './node_modules/@auditmation/types-core/schema/oauthTokenProfile.yml'

# connectionState.yml
$ref: './node_modules/@auditmation/types-core/schema/oauthTokenState.yml'
```

### Pattern 4: Custom Fields (Extend Core)

```yaml
# connectionProfile.yml - Add organizationId
allOf:
  - $ref: './node_modules/@auditmation/types-core/schema/tokenProfile.yml'
  - type: object
    required: [organizationId]
    properties:
      organizationId:
        type: string
        description: Organization identifier for API access

# connectionState.yml - Add extra state
allOf:
  - $ref: './node_modules/@auditmation/types-core/schema/tokenConnectionState.yml'
  - type: object
    properties:
      organizationName:
        type: string
        description: Cached organization name
```

## Connection Profile Scope

### What Belongs in connectionProfile

**ONLY connection parameters - minimal set needed to CONNECT**

```yaml
# βœ… GOOD - Connection parameters
- token / apiKey / clientId / clientSecret
- baseUrl (if API has multiple environments)
- organizationId (if required to authenticate)

# ❌ BAD - Operation parameters
- limit (pagination parameter)
- projectId (operation scope, not connection scope)
- fields (query parameter)
```

**Rule**: If you can connect WITHOUT it, it's an operation parameter (not profile)

### Check for Additional Optional Parameters

**Always review API docs for environment-specific optional parameters:**

```yaml
# Example: Service has optional region parameter
allOf:
  - $ref: './node_modules/@auditmation/types-core/schema/tokenProfile.yml'
  - type: object
    properties:
      region:
        type: string
        description: Optional region for multi-region deployments
        enum: [us-east-1, eu-west-1, ap-southeast-1]
    # region is optional, but include it if API docs mention it
```

**Don't omit parameters that some environments might need!**

## 🚨 CRITICAL: Check Parent Schema First

**Before adding ANY property, check what the parent schema provides:**

```bash
# Check what tokenProfile.yml provides
cat node_modules/@auditmation/types-core/schema/tokenProfile.yml

# Check what basicConnection.yml provides
cat node_modules/@auditmation/types-core/schema/basicConnection.yml

# Check what baseConnectionState.yml provides
cat node_modules/@auditmation/types-core/schema/baseConnectionState.yml
```

### Avoid Semantic Duplication

```yaml
# ❌ WRONG - basicConnection already has uri
allOf:
  - $ref: './node_modules/@auditmation/types-core/schema/basicConnection.yml'
  - type: object
    properties:
      url:    # Duplicate! basicConnection has uri
        type: string

# βœ… CORRECT - Use parent's uri, or extend if truly different
allOf:
  - $ref: './node_modules/@auditmation/types-core/schema/basicConnection.yml'
  # uri is already provided by basicConnection
```

**Semantic duplicates to avoid:**
- url / uri / baseUrl
- token / accessToken
- username / user / userName
- password / pass / pwd

## 🚨 CRITICAL: ALWAYS Check Product Documentation

**Before finalizing connectionProfile, check product docs for ALL auth parameters:**

```yaml
# Example: Missing mfaCode from product docs
allOf:
  - $ref: './node_modules/@auditmation/types-core/schema/basicConnection.yml'
  - type: object
    properties:
      mfaCode:    # Found in product docs!
        type: string
        description: Multi-factor authentication code (optional)
```

**Don't assume - verify:**
1. Read product documentation authentication section
2. Look for optional parameters (region, environment, mfaCode, etc.)
3. Include ALL mentioned parameters (even if optional)
4. Don't omit parameters some environments might need

## 🚨 CRITICAL: Connection Scope MUST NOT Limit Operations

**NEVER add organization/project/workspace IDs to connection:**

```yaml
# ❌ WRONG - Limits connection to single organization
connectionState:
  allOf:
    - $ref: './node_modules/@auditmation/types-core/schema/baseConnectionState.yml'
    - type: object
      properties:
        accessToken:
          type: string
        organizationId:    # NO! Limits scope
          type: string

# βœ… CORRECT - Connection works across all organizations
connectionState:
  allOf:
    - $ref: './node_modules/@auditmation/types-core/schema/baseConnectionState.yml'
    - type: object
      properties:
        accessToken:
          type: string
  # organizationId is operation parameter, NOT connection parameter
```

**WHY**: Connection should be reusable across all scopes. Use operation parameters for scope.

**Scope identifiers belong in operation parameters, NOT connection:**
- ❌ organizationId in connection
- ❌ workspaceId in connection
- ❌ projectId in connection
- ❌ teamId in connection
- βœ… These are operation parameters (use in API paths)

## 🚨 CRITICAL: Only Add Used Fields (for connectionState)

**For connectionState - don't add fields "just in case" - only add what's actually USED:**

```yaml
# ❌ WRONG - identityId not used anywhere
connectionState:
  properties:
    accessToken: string
    identityId: string    # Where is this used? Nowhere!

# βœ… CORRECT - Only fields that are actually used
connectionState:
  properties:
    accessToken: string
  # If connect() doesn't return identityId, don't add it
```

**Ask:**
1. Does connect() method return this field?
2. Do operations use this field?
3. Is it needed for refresh/reconnect?
If NO to all β†’ don't add it

**For connectionProfile - include environment-optional fields:**

```yaml
# βœ… CORRECT - Include optional fields that some environments need
allOf:
  - $ref: './node_modules/@auditmation/types-core/schema/tokenProfile.yml'
  - type: object
    properties:
      region:
        type: string
        description: Optional region (needed in some deployments)
      mfaCode:
        type: string
        description: Multi-factor authentication code (optional)
    # These aren't required, but include them if product docs mention them
```

**connectionProfile vs connectionState:**
- **connectionProfile**: Include optional fields that might be needed in some environments (region, mfaCode, etc.)
- **connectionState**: Only fields actually used by connect() or operations

## Validation Checklist

Before finalizing connection schemas:

- [ ] **Checked parent schema** - no semantic duplicates (url/uri, token/accessToken)
- [ ] **Checked product docs thoroughly** - all auth parameters included (mfaCode, region, etc.)
- [ ] connectionProfile extends a core profile (NOT custom)
- [ ] connectionState extends baseConnectionState (includes expiresIn)
- [ ] expiresIn is in seconds (integer), not expiresAt timestamp
- [ ] If refresh capability: state extends oauthTokenState
- [ ] If simple token: state extends tokenConnectionState
- [ ] Custom fields use allOf to extend core
- [ ] All required fields marked as required
- [ ] Checked API docs for optional connection parameters (region, environment, etc.)
- [ ] Profile contains ONLY connection parameters (not operation parameters)
- [ ] **NO scope limitation** - no organizationId/projectId/workspaceId in connection
- [ ] **Only used fields** - every state field is actually used by connect() or operations
- [ ] Minimal set needed to connect (don't add operation scope parameters)

## Common Mistakes

### ❌ Creating Custom Profile
```yaml
# DON'T DO THIS
type: object
properties:
  apiKey: string
  baseUrl: string
```
**Fix**: Extend tokenProfile.yml

### ❌ Missing baseConnectionState
```yaml
# DON'T DO THIS
type: object
properties:
  accessToken: string
```
**Fix**: Extend baseConnectionState or tokenConnectionState

### ❌ Using expiresAt Instead of expiresIn
```yaml
# DON'T DO THIS
expiresAt:
  type: string
  format: date-time
```
**Fix**: Convert to expiresIn (seconds) in connect() method

### ❌ No expiresIn for Refresh Tokens
```yaml
# DON'T DO THIS
properties:
  accessToken: string
  refreshToken: string
  # Missing expiresIn!
```
**Fix**: MUST extend baseConnectionState for expiresIn

## Remember

1. **Always extend core profiles** - Never create custom from scratch
2. **Always extend baseConnectionState** - Server needs expiresIn for cronjobs
3. **expiresIn in seconds** - Not timestamps, not milliseconds
4. **Use allOf for extensions** - Add custom fields via composition
5. **Receive data from @credential-manager** - Don't guess auth method

---

**Connection schemas are YAML schemas - design them like api.yml schemas!**

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.