Skip to content

Teams & Groups

Groups define who has access to what at Tractorbeam. A single group definition syncs across all systems - Okta, GitHub, AWS, Tailscale, and Google Workspace.

How Groups Work

┌─────────────────────────────────────────────────────────────────────────────┐
│       data/groups.json + data/accounts.json + data/projects.json           │
│                           (single source of truth)                          │
└─────────────────────────────────────────────────────────────────────────────┘


                            ┌─────────────────┐
                            │   Okta Groups   │
                            │  (Terraform)    │
                            └────────┬────────┘

           ┌─────────────┬───────────┼───────────┬─────────────┐
           │ SAML        │ SCIM      │ SCIM      │ SCIM        │
           ▼             ▼           ▼           ▼             ▼
     ┌──────────┐  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
     │  GitHub  │  │  AWS SSO │ │Tailscale │ │  Google  │ │  Slack   │
     │  Teams   │  │  Groups  │ │ ACL Tags │ │  Groups  │ │  Groups  │
     └──────────┘  └──────────┘ └──────────┘ └──────────┘ └──────────┘

Key principle: Define a group once, it appears everywhere it's needed.

Group Types

Functional Groups

Groups based on job function or team membership.

GroupDescriptionSyncs To
EmployeesAll full-time employeesGitHub, Google
ContractorsContract workers (separate for compliance)GitHub, Google
EngineeringEngineering teamGitHub, Google, AWS SSO
Platform-AdminsInfrastructure/DevOpsGitHub, Google, AWS SSO
SecuritySecurity teamGitHub, Google, AWS SSO
SupportCustomer supportGoogle
AccountingFinance teamGoogle

Per-Account AWS Groups

Auto-generated from data/accounts.json. Each account gets groups for access management.

Non-sandbox accounts get three groups:

Group PatternPurposeSSO Permission Set
AWS-User-{Name}Team access to the accountPowerUserAccess
AWS-Admin-{Name}Root email, account recovery (Platform-Admins auto-added)None (distribution only)
AWS-ReadOnly-{Name}Read-only investigation accessReadOnlyAccess

Sandbox accounts get one group:

Group PatternPurposeSSO Permission Set
AWS-Sandbox-{Owner}Sandbox owner + Platform-AdminsPowerUserAccess

Examples: AWS-Production, AWS-Admin-Audit, AWS-ReadOnly-Shared-Services, AWS-Sandbox-Wade

Project Groups

Groups for specific projects or client engagements. Defined in data/projects.json.

Projects are NOT AWS accounts. They're logical team groupings that scope repos and (future) K8s namespaces. A project deploys to one or more accounts but does NOT grant AWS access — that comes through AWS-* groups separately.

GroupDescription
Project-MailmanMailman product team (deploys to production, nonprod)
Project-CarlyleCarlyle engagement (deploys to carlyle)

Where Groups Appear

SystemGroup becomesUsed for
OktaGroupSource of truth, app assignments
GitHubTeamRepository access
AWS SSOGroup → Permission SetAccount access
TailscaleACL tagNetwork access rules
Google WorkspaceGoogle GroupEmail distribution, Drive sharing

Creating a New Group

1. Define in groups.json

Add to data/groups.json:

json
{
  "data_science": {
    "name": "Data-Science",
    "description": "Data science and ML team",
    "google_group": true,
    "github_team": true
  }
}

Fields:

  • name: Display name (use Title-Case with hyphens)
  • description: What this group is for
  • google_group: Create a Google Group for email
  • github_team: Create a GitHub team
  • aliases: (optional) Email aliases for Google Group

2. Apply Terraform

bash
cd okta && terraform apply     # Creates Okta group
cd ../github && terraform apply # Creates GitHub team (if github_team: true)

One-time manual step after creation:

  1. Go to github.com/orgs/tractorbeamai/teams/{team-slug}/settings
  2. Click Sync group → Select the matching Okta group → Save

4. Add Members in Okta

  1. Go to Okta Admin → Directory → Groups
  2. Find the group → People tab
  3. Add members

Members automatically sync to all connected systems.

Creating a Project Group

Projects are defined in data/projects.json. Projects scope repos and future K8s namespaces. They list which AWS accounts they deploy to as metadata, but this does NOT drive SSO assignments.

json
{
  "newclient": {
    "name": "NewClient",
    "description": "NewClient engagement team",
    "accounts": ["newclient"]
  }
}

This creates:

  • Okta group: Project-NewClient
  • GitHub team: project-newclient

AWS access is managed separately through AWS-* groups.

Modifying Group Membership

All membership changes happen in Okta. Changes sync automatically to other systems.

Adding a User to a Group

  1. Okta Admin → Directory → Groups → Select group
  2. Click Assign people
  3. Search and select users
  4. Click Save

Removing a User from a Group

  1. Okta Admin → Directory → Groups → Select group
  2. Find the user → Click X to remove
  3. Confirm removal

Sync Timing

SystemSync delay
GitHubUp to 1 hour (or immediate on SSO login)
AWS SSONear-instant (SCIM)
TailscaleNear-instant (SCIM)
GoogleNear-instant (SCIM)

Group Configuration Reference

data/groups.json

json
{
  "group_key": {
    "name": "Display-Name",
    "description": "What this group is for",
    "google_group": true,      // Create Google Group
    "github_team": true,       // Create GitHub team
    "aliases": ["alias1"]      // Google Group email aliases
  }
}

data/projects.json

json
{
  "project_key": {
    "name": "ProjectName",
    "description": "Project description",
    "accounts": ["production", "nonprod"]  // AWS accounts (metadata, not SSO)
  }
}

Troubleshooting

User not appearing in expected system

  1. Verify user is in the Okta group (Okta Admin → Groups → Members)
  2. For GitHub: Have user sign out/in via SSO, or wait up to 1 hour
  3. For AWS: Check SCIM provisioning logs in Okta
  4. For Google: Check Group Push status in Okta

Group missing in a system

  1. Verify the group has the correct flag (github_team, google_group)
  2. Check Terraform was applied (cd okta && terraform plan)
  3. For GitHub: Verify team is linked to Okta group

Changes not syncing

  1. Check Okta app provisioning status (Applications → App → Provisioning)
  2. Look for SCIM errors in Okta system log
  3. For GitHub specifically: SAML team sync requires user login to trigger

Infrastructure

FilePurpose
data/groups.jsonFunctional group definitions
data/accounts.jsonAWS account definitions (drives per-account groups)
data/projects.jsonProject group definitions
okta/groups.tfCreates Okta groups, assigns to apps
github/main.tfCreates GitHub teams

See Identity Integration for the complete architecture.