googleworkspacedirectorysync

package
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 21, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package googleworkspacedirectorysync pulls the Google Workspace user directory and upserts it into saas_identities. Until this package landed, no production producer wrote to saas_identities for ANY provider — Security Graph and the executive report sourced their identity / MFA / privileged-account counts from a table that only the demo seed populated, so live tenants always saw zero. This sync closes that gap for Google.

Why a separate binary from the audit-log poller: the two read different Google APIs (admin.reports vs admin.directory), have different rate limits, and progress on very different cadences — audit-logs are minute-fresh and drive findings; the directory typically only shifts when employees join, leave, or get promoted. Running them in the same loop would force them to share an interval and would couple a Directory API outage to the audit pipeline's recovery latency.

Design notes:

  • The Directory API has no streaming "since" filter; the sync does a full users.list page-walk on every tick. For a typical workspace (low thousands of users) that completes in seconds.
  • Pagination uses nextPageToken; maxPagesPerTick bounds runaway fetches the same way the audit poller's maxPagesPerApp does.
  • HTTP failures on a single integration update last_error and continue to the next integration; one broken tenant must not freeze the fleet.
  • The saas_identities upsert is keyed on (organization_id, provider, external_id) — Google's stable user id — so renames, email changes, and re-provisioning all converge on the same row.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type OAuthConfig

type OAuthConfig struct {
	ClientID     string
	ClientSecret string
}

OAuthConfig and OAuthResolver mirror the audit poller's signatures so the bootstrap-side resolver can be reused without an import cycle.

type OAuthResolver

type OAuthResolver interface {
	ResolveGoogleOAuthClient(ctx context.Context, organizationID string) (OAuthConfig, bool)
}

type Sync

type Sync struct {
	// contains filtered or unexported fields
}

Sync is the long-running goroutine that drives directory ingestion.

func New

func New(db *sql.DB, resolver OAuthResolver) *Sync

func (*Sync) Run

func (s *Sync) Run(ctx context.Context) error

Run blocks until ctx is cancelled, ticking every interval. The first tick fires immediately so a freshly-connected integration does not have to wait a full interval before users appear in saas_identities.

func (*Sync) Tick

func (s *Sync) Tick(ctx context.Context) error

Tick performs one sweep across all connected Google Workspace integrations.

func (*Sync) WakeIntegration

func (s *Sync) WakeIntegration(ctx context.Context, integrationID string) error

func (*Sync) WithHTTPClient

func (s *Sync) WithHTTPClient(c *http.Client) *Sync

func (*Sync) WithInterval

func (s *Sync) WithInterval(d time.Duration) *Sync

func (*Sync) WithMaxPages

func (s *Sync) WithMaxPages(n int) *Sync

func (*Sync) WithNowFn

func (s *Sync) WithNowFn(fn func() time.Time) *Sync

func (*Sync) WithPageSize

func (s *Sync) WithPageSize(n int) *Sync

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL