Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

anthropic api key analyzer #3878

Open
wants to merge 13 commits into
base: main
Choose a base branch
from

Conversation

kashifkhan0771
Copy link
Contributor

Description:

This PR add a new analyzer for anthropic detector

Test Cases:

Screenshot from 2025-02-06 18-18-04
Screenshot from 2025-02-06 18-19-12

Checklist:

  • Tests passing (make test-community)?
  • Lint passing (make lint this requires golangci-lint)?

@kashifkhan0771 kashifkhan0771 requested review from a team as code owners February 6, 2025 13:22
Copy link
Collaborator

@ahrav ahrav left a comment

Choose a reason for hiding this comment

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

I don't have a ton of experience reviewing Analyzers, so if any of my comments feel strange, just ignore them 😅

// SecretInfo hold the information about the anthropic key
type SecretInfo struct {
Valid bool
Type string // key type - TODO: Handle Anthropic Admin Keys
Copy link
Collaborator

Choose a reason for hiding this comment

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

question: Is this still a TODO, or is this a relic?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's a TODO. Right now our anthropic detector does not detect Admin Keys. Once we update the detector we can update the analyzer as well to work with both type of keys.

}

// AnthropicResource is any resource that can be accessed with anthropic key
type AnthropicResource struct {
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: To reduce stutter, we can rename this to Resource, making imports cleaner—anthropic.Resource instead of anthropic.AnthropicResource. If all of our analyzers already have naming like this, please feel free to ignore this comment.

ref1
ref2

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Makes sense, the reason I did this is to avoid the confusion between AnalyzerResult Binding Resource and Anthropic Resource.
@abmussani @zricethezav your thoughts? Shall we go with this name or rename it to just Resource?

}

bodyBytes, err := json.Marshal(body)
// https://docs.anthropic.com/en/api/models-list
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nice change!

@@ -104,23 +104,6 @@ func TestAnthropic_FromChunk(t *testing.T) {
wantErr: false,
wantVerificationErr: true,
},
{
Copy link
Collaborator

Choose a reason for hiding this comment

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

question: Are we no longer concerned with this test case?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Honestly, I don't know. This test case was failing with valid secret so I removed it 😆


var secretInfo = &SecretInfo{}

secretInfo.Type = "API-Key" // TODO: implement Admin-Key type as well
Copy link
Collaborator

Choose a reason for hiding this comment

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

question: Do you think we can make this "magic" string a const?

// create a HTTP client
client := analyzers.NewAnalyzeClient(cfg)

var secretInfo = &SecretInfo{}
Copy link
Collaborator

Choose a reason for hiding this comment

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

question/suggestion: Is there a reason you used an empty variable declaration followed by setting the Type field, instead of a single assignment? I'm not very familiar with analyzers, so if this is standard practice in the codebase, feel free to disregard.

Ex:
secretInfo := &SecretInfo{Type: "API-Key"}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My bad! 😶‍🌫️


// anthropic key has full access only
secretInfo.Permissions = PermissionStrings[FullAccess]
secretInfo.Valid = true
Copy link
Collaborator

Choose a reason for hiding this comment

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

question: Is there ever a scenario where secretInfo.Valid = false?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, it happens when the key passed is not valid. We print this on terminal. Once we are able to get resources that mean the key is valid.


result := analyzers.AnalyzerResult{
AnalyzerType: analyzers.AnalyzerAnthropic,
Metadata: map[string]any{},
Copy link
Collaborator

Choose a reason for hiding this comment

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

question: It looks like the Metadata is just Valid_Key. Could we just set it here directly?
Metadata: map[string]any{"Valid_Key": info.Valid}

result := analyzers.AnalyzerResult{
AnalyzerType: analyzers.AnalyzerAnthropic,
Metadata: map[string]any{},
Bindings: make([]analyzers.Binding, 0),
Copy link
Collaborator

Choose a reason for hiding this comment

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

suggestion: Looks like we can pre-allocate this slice.
make([]analyzers.Binding, 0, len(info.AnthropicResources))

}

// secretInfoToAnalyzerResult translate secret info to Analyzer Result
func secretInfoToAnalyzerResult(info *SecretInfo) *analyzers.AnalyzerResult {
Copy link
Collaborator

Choose a reason for hiding this comment

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

question: It looks like we collect AnthropicResources from listModels and listMessageBatches in *SecretInfo, then iterate over them again to create Bindings. Could we skip the intermediary *SecretItem and build Bindings directly by passing it to listModels and listMessageBatches? That seems like it would eliminate the extra iteration. I might be missing something, so feel free to correct me if I'm off base.

Copy link
Collaborator

Choose a reason for hiding this comment

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

EDIT: After reviewing another analyzer, I don't think we should buck the trend of how these currently work. Please ignore the above comment.

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

Successfully merging this pull request may close these issues.

2 participants