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 ¶
- type OAuthConfig
- type OAuthResolver
- type Sync
- func (s *Sync) Run(ctx context.Context) error
- func (s *Sync) Tick(ctx context.Context) error
- func (s *Sync) WakeIntegration(ctx context.Context, integrationID string) error
- func (s *Sync) WithHTTPClient(c *http.Client) *Sync
- func (s *Sync) WithInterval(d time.Duration) *Sync
- func (s *Sync) WithMaxPages(n int) *Sync
- func (s *Sync) WithNowFn(fn func() time.Time) *Sync
- func (s *Sync) WithPageSize(n int) *Sync
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type OAuthConfig ¶
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 (*Sync) Run ¶
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.