Skip to content

Commit dffa08e

Browse files
richardpark-msftripark
andauthored
feat(azure): allow passing custom scopes (#541)
Co-authored-by: ripark <[email protected]>
1 parent cf50c53 commit dffa08e

File tree

2 files changed

+73
-17
lines changed

2 files changed

+73
-17
lines changed

azure/azure.go

Lines changed: 47 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -91,30 +91,60 @@ func WithEndpoint(endpoint string, apiVersion string) option.RequestOption {
9191
})
9292
}
9393

94+
type tokenCredentialConfig struct {
95+
Scopes []string
96+
}
97+
98+
// TokenCredentialOption is the type for any options that can be used to customize
99+
// [WithTokenCredential], including things like using custom scopes.
100+
type TokenCredentialOption func(*tokenCredentialConfig) error
101+
102+
// WithTokenCredentialScopes overrides the default scope used when requesting access tokens.
103+
func WithTokenCredentialScopes(scopes []string) func(*tokenCredentialConfig) error {
104+
return func(tc *tokenCredentialConfig) error {
105+
tc.Scopes = scopes
106+
return nil
107+
}
108+
}
109+
94110
// WithTokenCredential configures this client to authenticate using an [Azure Identity] TokenCredential.
95111
// This function should be paired with a call to [WithEndpoint] to point to your Azure OpenAI instance.
96112
//
97113
// [Azure Identity]: https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity
98-
func WithTokenCredential(tokenCredential azcore.TokenCredential) option.RequestOption {
99-
bearerTokenPolicy := runtime.NewBearerTokenPolicy(tokenCredential, []string{"https://cognitiveservices.azure.com/.default"}, nil)
100-
101-
// add in a middleware that uses the bearer token generated from the token credential
102-
return option.WithMiddleware(func(req *http.Request, next option.MiddlewareNext) (*http.Response, error) {
103-
pipeline := runtime.NewPipeline("azopenai-extensions", version, runtime.PipelineOptions{}, &policy.ClientOptions{
104-
InsecureAllowCredentialWithHTTP: true, // allow for plain HTTP proxies, etc..
105-
PerRetryPolicies: []policy.Policy{
106-
bearerTokenPolicy,
107-
policyAdapter(next),
108-
},
109-
})
110-
111-
req2, err := runtime.NewRequestFromRequest(req)
114+
func WithTokenCredential(tokenCredential azcore.TokenCredential, options ...TokenCredentialOption) option.RequestOption {
115+
return requestconfig.RequestOptionFunc(func(rc *requestconfig.RequestConfig) error {
116+
tc := &tokenCredentialConfig{
117+
Scopes: []string{"https://cognitiveservices.azure.com/.default"},
118+
}
112119

113-
if err != nil {
114-
return nil, err
120+
for _, option := range options {
121+
if err := option(tc); err != nil {
122+
return err
123+
}
115124
}
116125

117-
return pipeline.Do(req2)
126+
bearerTokenPolicy := runtime.NewBearerTokenPolicy(tokenCredential, tc.Scopes, nil)
127+
128+
// add in a middleware that uses the bearer token generated from the token credential
129+
middlewareOption := option.WithMiddleware(func(req *http.Request, next option.MiddlewareNext) (*http.Response, error) {
130+
pipeline := runtime.NewPipeline("azopenai-extensions", version, runtime.PipelineOptions{}, &policy.ClientOptions{
131+
InsecureAllowCredentialWithHTTP: true, // allow for plain HTTP proxies, etc..
132+
PerRetryPolicies: []policy.Policy{
133+
bearerTokenPolicy,
134+
policyAdapter(next),
135+
},
136+
})
137+
138+
req2, err := runtime.NewRequestFromRequest(req)
139+
140+
if err != nil {
141+
return nil, err
142+
}
143+
144+
return pipeline.Do(req2)
145+
})
146+
147+
return middlewareOption.Apply(rc)
118148
})
119149
}
120150

azure/example_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,29 @@ func Example_authentication() {
4545
_ = client
4646
}
4747
}
48+
49+
func Example_authentication_custom_scopes() {
50+
// Custom scopes can also be passed, if needed, when using Azure OpenAI endpoints.
51+
const azureOpenAIEndpoint = "https://<your-azureopenai-instance>.openai.azure.com"
52+
const azureOpenAIAPIVersion = "<api version string>"
53+
54+
// For a full list of credential types look at the documentation for the Azure Identity
55+
// package: https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity
56+
tokenCredential, err := azidentity.NewDefaultAzureCredential(nil)
57+
58+
if err != nil {
59+
fmt.Printf("Failed to create TokenCredential: %s\n", err)
60+
return
61+
}
62+
63+
client := openai.NewClient(
64+
azure.WithEndpoint(azureOpenAIEndpoint, azureOpenAIAPIVersion),
65+
azure.WithTokenCredential(tokenCredential,
66+
// This is an example of a custom scope. See documentation for your service
67+
// endpoint for the proper value to pass.
68+
azure.WithTokenCredentialScopes([]string{"your-custom-scope"}),
69+
),
70+
)
71+
72+
_ = client
73+
}

0 commit comments

Comments
 (0)