Skip to content

chore: adds org lookup type to instrumentation data#609

Open
j-luong wants to merge 1 commit into
mainfrom
chore/cli-1372_addOrgLookupInstrumentationData
Open

chore: adds org lookup type to instrumentation data#609
j-luong wants to merge 1 commit into
mainfrom
chore/cli-1372_addOrgLookupInstrumentationData

Conversation

@j-luong
Copy link
Copy Markdown
Contributor

@j-luong j-luong commented May 18, 2026

Description

This PR adds some extra instrumentation data to how we perform org lookups.

Checklist

  • Tests added and all succeed (make test)
  • Regenerated mocks, etc. (make generate)
  • Linted (make lint)
  • Test your changes work for the CLI
    1. Clone / pull the latest CLI main.
    2. Run go get github.com/snyk/go-application-framework@YOUR_LATEST_GAF_COMMIT in the cliv2 directory.
      • Tip: for local testing, you can uncomment the line near the bottom of the CLI's go.mod to point to your local GAF code.
    3. Run go mod tidy in the cliv2 directory.
    4. Run the CLI tests and do any required manual testing.
    5. Open a PR in the CLI repo now with the go.mod and go.sum changes.
    • Once this PR is merged, repeat these steps, but pointing to the latest GAF commit on main and update your CLI PR.

@j-luong j-luong requested review from a team as code owners May 18, 2026 13:25
@snyk-io
Copy link
Copy Markdown

snyk-io Bot commented May 18, 2026

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues
Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@snyk-io
Copy link
Copy Markdown

snyk-io Bot commented May 18, 2026

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues
Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@snyk-pr-review-bot

This comment has been minimized.

@j-luong j-luong force-pushed the chore/cli-1372_addOrgLookupInstrumentationData branch 2 times, most recently from 2381e2f to a48fa86 Compare May 18, 2026 13:45
@snyk-pr-review-bot

This comment has been minimized.

@snyk-pr-review-bot

This comment has been minimized.

Comment thread pkg/app/app.go Outdated
Comment thread pkg/app/app.go Outdated
Comment thread pkg/app/app.go Outdated
orgId, err = apiClient.GetOrgIdFromSlug(context.Background(), existingString)
if err != nil {
logger.Print("Failed to determine default value for \"ORGANIZATION\":", err)
addLookupType("invalid")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: maybe be a bit more explicit and self explaining in the data. Consider a case that someone will just have the instrumentation data, will it be self explaining?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thinking of the more complete picture (name: value)

  • organization-id-origin: defaultid-failed-slugname-lookup
  • organization-id-origin: defaultid-not-user-supplied
  • organization-id-origin: slugname-lookup
  • organization-id-origin: user-supplied

I don't like my proposal but maybe still food for thought?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

made an opinionated change, let me know if it works

Comment thread pkg/app/app.go Outdated
@j-luong j-luong force-pushed the chore/cli-1372_addOrgLookupInstrumentationData branch from a48fa86 to c692c0f Compare May 18, 2026 19:01
@snyk-pr-review-bot

This comment has been minimized.

@j-luong j-luong force-pushed the chore/cli-1372_addOrgLookupInstrumentationData branch from c692c0f to 64b7ff4 Compare May 18, 2026 19:04
@snyk-pr-review-bot

This comment has been minimized.

Comment thread pkg/app/app.go Outdated
slugName, err := apiClient.GetSlugFromOrgId(context.Background(), orgId)
if err != nil {
logger.Print("Failed to determine default value for \"ORGANIZATION_SLUG\":", err)
recorder.addExtension(orgLookupKey, "invalid")
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

context: a command like snyk test --org=<INVALID_UUID> will result in the orgLookupkey value being orgid instead of invalid

@j-luong j-luong force-pushed the chore/cli-1372_addOrgLookupInstrumentationData branch 2 times, most recently from 07ab378 to d0060e0 Compare May 19, 2026 09:21
@snyk-pr-review-bot

This comment has been minimized.

@snyk-pr-review-bot

This comment has been minimized.

a := analytics.New()
a.SetIntegration(e.config.GetString(configuration.INTEGRATION_NAME), e.config.GetString(configuration.INTEGRATION_VERSION))
a.SetApiUrl(e.config.GetString(configuration.API_URL))
a.SetOrg(e.config.GetString(configuration.ORGANIZATION))
Copy link
Copy Markdown
Contributor Author

@j-luong j-luong May 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

context: calling this before we finish initialising our engine means our analytics is not initialised and will lead to it being nil when trying to use it in our config.DefaultValueFunction.

The consequence is that we have to set this where we use GAF (e.g. CLI) instead.

Possibly a controversial change but, without this, we won't get analytics implemented in the rest of the PR. Additionally, the argument could be made that none of these "Sets" should be a GAF concern.

@j-luong j-luong force-pushed the chore/cli-1372_addOrgLookupInstrumentationData branch 3 times, most recently from 5fae914 to fc5e2f6 Compare May 19, 2026 10:26
@snyk-pr-review-bot
Copy link
Copy Markdown

PR Reviewer Guide 🔍

🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Telemetry Regression 🟠 [major]

Removing the call to a.SetOrg() in initAnalytics() prevents the organization ID from being associated with the global analytics object. The reference code in pkg/analytics/analytics.go shows that the org query parameter is only added to the analytics POST request if this field is populated. Removing this call will cause all background telemetry to be sent without an organization identifier in the URL, likely breaking server-side attribution and filtering that relies on the query parameter.

func (e *EngineImpl) initAnalytics() analytics.Analytics {
	a := analytics.New()
	a.SetIntegration(e.config.GetString(configuration.INTEGRATION_NAME), e.config.GetString(configuration.INTEGRATION_VERSION))
	a.SetApiUrl(e.config.GetString(configuration.API_URL))
	a.SetClient(func() *http.Client {
		return e.networkAccess.GetHttpClient()
	})
Instrumentation Data Loss 🟡 [minor]

The newInstrumentationRecorder helper silently discards telemetry data if the engine's analytics object has not yet been initialized. In pkg/workflow/engineimpl.go, Init() executes extension initializers before calling initAnalytics(). If any extension triggers an organization lookup during its initialization (a common scenario for resolving context), the resulting instrumentation data will be lost because engine.GetAnalytics() will return nil at that point.

func newInstrumentationRecorder(engine workflow.Engine) instrumentationRecorder {
	r := instrumentationRecorder{}
	if a := engine.GetAnalytics(); a != nil {
		r.ic = a.GetInstrumentation()
	}
	return r
}
📚 Repository Context Analyzed

This review considered 10 relevant code sections from 7 files (average relevance: 0.92)

@snyk-pr-review-bot
Copy link
Copy Markdown

PR Reviewer Guide 🔍

🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Loss of Organization Context 🟠 [major]

The removal of a.SetOrg() in initAnalytics() prevents the organization identifier from being associated with the Analytics object during initialization. According to the GetRequest() implementation in pkg/analytics/analytics.go (see cross-file context), the org field is used to append an org query parameter to the analytics API request URL. Without this being set, all telemetry sent by the engine will lose its organization association, likely breaking server-side filtering or attribution.

func (e *EngineImpl) initAnalytics() analytics.Analytics {
	a := analytics.New()
	a.SetIntegration(e.config.GetString(configuration.INTEGRATION_NAME), e.config.GetString(configuration.INTEGRATION_VERSION))
	a.SetApiUrl(e.config.GetString(configuration.API_URL))
	a.SetClient(func() *http.Client {
		return e.networkAccess.GetHttpClient()
	})
Telemetry Silent Failure 🟡 [minor]

The newInstrumentationRecorder function retrieves analytics via engine.GetAnalytics(). However, in the CreateAppEngineWithOptions flow, initConfiguration (which invokes these default functions) is called BEFORE engine.Init(). Since engine.analytics is only initialized during Init() (in engineimpl.go), the GetAnalytics() call will return nil during the initial configuration phase. This causes the new instrumentation to silently skip recording any data during the very lookup process it was designed to monitor.

func newInstrumentationRecorder(engine workflow.Engine) instrumentationRecorder {
	r := instrumentationRecorder{}
	if a := engine.GetAnalytics(); a != nil {
		r.ic = a.GetInstrumentation()
	}
	return r
}
📚 Repository Context Analyzed

This review considered 10 relevant code sections from 7 files (average relevance: 0.92)

@snyk-pr-review-bot

This comment has been minimized.

@j-luong j-luong force-pushed the chore/cli-1372_addOrgLookupInstrumentationData branch from fc5e2f6 to d62b09f Compare May 19, 2026 10:32
@snyk-pr-review-bot

This comment has been minimized.

Comment thread pkg/app/app.go
Copy link
Copy Markdown
Contributor

@robertolopezlopez robertolopezlopez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@j-luong j-luong force-pushed the chore/cli-1372_addOrgLookupInstrumentationData branch 3 times, most recently from 2355c76 to 2926e93 Compare May 20, 2026 16:03
@snyk-pr-review-bot

This comment has been minimized.

@j-luong j-luong force-pushed the chore/cli-1372_addOrgLookupInstrumentationData branch from 2926e93 to c125106 Compare May 20, 2026 16:26
Comment thread pkg/app/app.go

const (
// orgLookupSourceKey records how the ORGANIZATION value was resolved.
orgLookupSourceKey = "gaf.app.defaultfunc.organization.lookup"
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

context: key tries to define the kind of data we're assessing in OTel standard dot . notation.
The idea is to break it down as follows: <project>.<package|scope>.<method>.<property>.<detail>.

@snyk-pr-review-bot
Copy link
Copy Markdown

PR Reviewer Guide 🔍

🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Ambiguous Telemetry 🟡 [minor]

In defaultFuncOrganization, when a UUID is provided directly, orgLookupProvidedID is recorded. However, unlike the slug lookup path which validates the slug against the API, the ID path returns the value immediately without verification. This results in telemetry that treats any syntactically valid UUID as a successful lookup, even if that ID does not exist or the user lacks access, making it indistinguishable from valid lookups in instrumentation data.

instrumentation.addExtension(orgLookupSourceKey, orgLookupProvidedID)
return orgId, nil
📚 Repository Context Analyzed

This review considered 10 relevant code sections from 6 files (average relevance: 0.84)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants