Skip to content

Commit a2fc4ac

Browse files
feat: Enhance agent authentication with optional login page URL and auth ch…
1 parent 628410a commit a2fc4ac

File tree

8 files changed

+738
-4
lines changed

8 files changed

+738
-4
lines changed

.stats.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
configured_endpoints: 74
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-3a68acd8c46e121c66be5b4c30bb4e962967840ca0f31070905baa39635fbc2d.yml
3-
openapi_spec_hash: 9453963fbb01de3e0afb462b16cdf115
4-
config_hash: 6dbe88d2ba9df1ec46cedbfdb7d00000
1+
configured_endpoints: 80
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-8a37652fa586b8932466d16285359a89988505f850787f8257d0c4c7053da173.yml
3+
openapi_spec_hash: 042765a113f6d08109e8146b302323ec
4+
config_hash: 113f1e5bc3567628a5d51c70bc00969d

agent.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
package kernel
4+
5+
import (
6+
"github.com/onkernel/kernel-go-sdk/option"
7+
)
8+
9+
// AgentService contains methods and other services that help with interacting with
10+
// the kernel API.
11+
//
12+
// Note, unlike clients, this service does not read variables from the environment
13+
// automatically. You should not instantiate this service directly, and instead use
14+
// the [NewAgentService] method instead.
15+
type AgentService struct {
16+
Options []option.RequestOption
17+
Auth AgentAuthService
18+
}
19+
20+
// NewAgentService generates a new service that applies the given options to each
21+
// request. These options are applied after the parent client's options (if there
22+
// is one), and before any request-specific options.
23+
func NewAgentService(opts ...option.RequestOption) (r AgentService) {
24+
r = AgentService{}
25+
r.Options = opts
26+
r.Auth = NewAgentAuthService(opts...)
27+
return
28+
}

agentauth.go

Lines changed: 325 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,325 @@
1+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
package kernel
4+
5+
import (
6+
"context"
7+
"errors"
8+
"fmt"
9+
"net/http"
10+
"slices"
11+
"time"
12+
13+
"github.com/onkernel/kernel-go-sdk/internal/apijson"
14+
"github.com/onkernel/kernel-go-sdk/internal/requestconfig"
15+
"github.com/onkernel/kernel-go-sdk/option"
16+
"github.com/onkernel/kernel-go-sdk/packages/param"
17+
"github.com/onkernel/kernel-go-sdk/packages/respjson"
18+
)
19+
20+
// AgentAuthService contains methods and other services that help with interacting
21+
// with the kernel API.
22+
//
23+
// Note, unlike clients, this service does not read variables from the environment
24+
// automatically. You should not instantiate this service directly, and instead use
25+
// the [NewAgentAuthService] method instead.
26+
type AgentAuthService struct {
27+
Options []option.RequestOption
28+
Invocations AgentAuthInvocationService
29+
}
30+
31+
// NewAgentAuthService generates a new service that applies the given options to
32+
// each request. These options are applied after the parent client's options (if
33+
// there is one), and before any request-specific options.
34+
func NewAgentAuthService(opts ...option.RequestOption) (r AgentAuthService) {
35+
r = AgentAuthService{}
36+
r.Options = opts
37+
r.Invocations = NewAgentAuthInvocationService(opts...)
38+
return
39+
}
40+
41+
// Retrieve an auth agent by its ID. Returns the current authentication status of
42+
// the managed profile.
43+
func (r *AgentAuthService) Get(ctx context.Context, id string, opts ...option.RequestOption) (res *AuthAgent, err error) {
44+
opts = slices.Concat(r.Options, opts)
45+
if id == "" {
46+
err = errors.New("missing required id parameter")
47+
return
48+
}
49+
path := fmt.Sprintf("agents/auth/%s", id)
50+
err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...)
51+
return
52+
}
53+
54+
// Creates a browser session and returns a handoff code for the hosted flow. Uses
55+
// standard API key or JWT authentication (not the JWT returned by the exchange
56+
// endpoint).
57+
func (r *AgentAuthService) Start(ctx context.Context, body AgentAuthStartParams, opts ...option.RequestOption) (res *AgentAuthStartResponse, err error) {
58+
opts = slices.Concat(r.Options, opts)
59+
path := "agents/auth/start"
60+
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...)
61+
return
62+
}
63+
64+
// Response from discover endpoint matching AuthBlueprint schema
65+
type AgentAuthDiscoverResponse struct {
66+
// Whether discovery succeeded
67+
Success bool `json:"success,required"`
68+
// Error message if discovery failed
69+
ErrorMessage string `json:"error_message"`
70+
// Discovered form fields (present when success is true)
71+
Fields []DiscoveredField `json:"fields"`
72+
// Whether user is already logged in
73+
LoggedIn bool `json:"logged_in"`
74+
// URL of the discovered login page
75+
LoginURL string `json:"login_url" format:"uri"`
76+
// Title of the login page
77+
PageTitle string `json:"page_title"`
78+
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
79+
JSON struct {
80+
Success respjson.Field
81+
ErrorMessage respjson.Field
82+
Fields respjson.Field
83+
LoggedIn respjson.Field
84+
LoginURL respjson.Field
85+
PageTitle respjson.Field
86+
ExtraFields map[string]respjson.Field
87+
raw string
88+
} `json:"-"`
89+
}
90+
91+
// Returns the unmodified JSON received from the API
92+
func (r AgentAuthDiscoverResponse) RawJSON() string { return r.JSON.raw }
93+
func (r *AgentAuthDiscoverResponse) UnmarshalJSON(data []byte) error {
94+
return apijson.UnmarshalRoot(data, r)
95+
}
96+
97+
// Response from get invocation endpoint
98+
type AgentAuthInvocationResponse struct {
99+
// App name (org name at time of invocation creation)
100+
AppName string `json:"app_name,required"`
101+
// When the handoff code expires
102+
ExpiresAt time.Time `json:"expires_at,required" format:"date-time"`
103+
// Invocation status
104+
//
105+
// Any of "IN_PROGRESS", "SUCCESS", "EXPIRED", "CANCELED".
106+
Status AgentAuthInvocationResponseStatus `json:"status,required"`
107+
// Target domain for authentication
108+
TargetDomain string `json:"target_domain,required"`
109+
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
110+
JSON struct {
111+
AppName respjson.Field
112+
ExpiresAt respjson.Field
113+
Status respjson.Field
114+
TargetDomain respjson.Field
115+
ExtraFields map[string]respjson.Field
116+
raw string
117+
} `json:"-"`
118+
}
119+
120+
// Returns the unmodified JSON received from the API
121+
func (r AgentAuthInvocationResponse) RawJSON() string { return r.JSON.raw }
122+
func (r *AgentAuthInvocationResponse) UnmarshalJSON(data []byte) error {
123+
return apijson.UnmarshalRoot(data, r)
124+
}
125+
126+
// Invocation status
127+
type AgentAuthInvocationResponseStatus string
128+
129+
const (
130+
AgentAuthInvocationResponseStatusInProgress AgentAuthInvocationResponseStatus = "IN_PROGRESS"
131+
AgentAuthInvocationResponseStatusSuccess AgentAuthInvocationResponseStatus = "SUCCESS"
132+
AgentAuthInvocationResponseStatusExpired AgentAuthInvocationResponseStatus = "EXPIRED"
133+
AgentAuthInvocationResponseStatusCanceled AgentAuthInvocationResponseStatus = "CANCELED"
134+
)
135+
136+
// Response from starting an agent authentication invocation
137+
type AgentAuthStartResponse struct {
138+
// Unique identifier for the auth agent managing this domain/profile
139+
AuthAgentID string `json:"auth_agent_id,required"`
140+
// When the handoff code expires
141+
ExpiresAt time.Time `json:"expires_at,required" format:"date-time"`
142+
// One-time code for handoff
143+
HandoffCode string `json:"handoff_code,required"`
144+
// URL to redirect user to
145+
HostedURL string `json:"hosted_url,required" format:"uri"`
146+
// Unique identifier for the invocation
147+
InvocationID string `json:"invocation_id,required"`
148+
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
149+
JSON struct {
150+
AuthAgentID respjson.Field
151+
ExpiresAt respjson.Field
152+
HandoffCode respjson.Field
153+
HostedURL respjson.Field
154+
InvocationID respjson.Field
155+
ExtraFields map[string]respjson.Field
156+
raw string
157+
} `json:"-"`
158+
}
159+
160+
// Returns the unmodified JSON received from the API
161+
func (r AgentAuthStartResponse) RawJSON() string { return r.JSON.raw }
162+
func (r *AgentAuthStartResponse) UnmarshalJSON(data []byte) error {
163+
return apijson.UnmarshalRoot(data, r)
164+
}
165+
166+
// Response from submit endpoint matching SubmitResult schema
167+
type AgentAuthSubmitResponse struct {
168+
// Whether submission succeeded
169+
Success bool `json:"success,required"`
170+
// Additional fields needed (e.g., OTP) - present when needs_additional_auth is
171+
// true
172+
AdditionalFields []DiscoveredField `json:"additional_fields"`
173+
// App name (only present when logged_in is true)
174+
AppName string `json:"app_name"`
175+
// Error message if submission failed
176+
ErrorMessage string `json:"error_message"`
177+
// Whether user is now logged in
178+
LoggedIn bool `json:"logged_in"`
179+
// Whether additional authentication fields are needed
180+
NeedsAdditionalAuth bool `json:"needs_additional_auth"`
181+
// Target domain (only present when logged_in is true)
182+
TargetDomain string `json:"target_domain"`
183+
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
184+
JSON struct {
185+
Success respjson.Field
186+
AdditionalFields respjson.Field
187+
AppName respjson.Field
188+
ErrorMessage respjson.Field
189+
LoggedIn respjson.Field
190+
NeedsAdditionalAuth respjson.Field
191+
TargetDomain respjson.Field
192+
ExtraFields map[string]respjson.Field
193+
raw string
194+
} `json:"-"`
195+
}
196+
197+
// Returns the unmodified JSON received from the API
198+
func (r AgentAuthSubmitResponse) RawJSON() string { return r.JSON.raw }
199+
func (r *AgentAuthSubmitResponse) UnmarshalJSON(data []byte) error {
200+
return apijson.UnmarshalRoot(data, r)
201+
}
202+
203+
// An auth agent that manages authentication for a specific domain and profile
204+
// combination
205+
type AuthAgent struct {
206+
// Unique identifier for the auth agent
207+
ID string `json:"id,required"`
208+
// Target domain for authentication
209+
Domain string `json:"domain,required"`
210+
// Name of the profile associated with this auth agent
211+
ProfileName string `json:"profile_name,required"`
212+
// Current authentication status of the managed profile
213+
//
214+
// Any of "AUTHENTICATED", "NEEDS_AUTH".
215+
Status AuthAgentStatus `json:"status,required"`
216+
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
217+
JSON struct {
218+
ID respjson.Field
219+
Domain respjson.Field
220+
ProfileName respjson.Field
221+
Status respjson.Field
222+
ExtraFields map[string]respjson.Field
223+
raw string
224+
} `json:"-"`
225+
}
226+
227+
// Returns the unmodified JSON received from the API
228+
func (r AuthAgent) RawJSON() string { return r.JSON.raw }
229+
func (r *AuthAgent) UnmarshalJSON(data []byte) error {
230+
return apijson.UnmarshalRoot(data, r)
231+
}
232+
233+
// Current authentication status of the managed profile
234+
type AuthAgentStatus string
235+
236+
const (
237+
AuthAgentStatusAuthenticated AuthAgentStatus = "AUTHENTICATED"
238+
AuthAgentStatusNeedsAuth AuthAgentStatus = "NEEDS_AUTH"
239+
)
240+
241+
// A discovered form field
242+
type DiscoveredField struct {
243+
// Field label
244+
Label string `json:"label,required"`
245+
// Field name
246+
Name string `json:"name,required"`
247+
// CSS selector for the field
248+
Selector string `json:"selector,required"`
249+
// Field type
250+
//
251+
// Any of "text", "email", "password", "tel", "number", "url", "code".
252+
Type DiscoveredFieldType `json:"type,required"`
253+
// Field placeholder
254+
Placeholder string `json:"placeholder"`
255+
// Whether field is required
256+
Required bool `json:"required"`
257+
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
258+
JSON struct {
259+
Label respjson.Field
260+
Name respjson.Field
261+
Selector respjson.Field
262+
Type respjson.Field
263+
Placeholder respjson.Field
264+
Required respjson.Field
265+
ExtraFields map[string]respjson.Field
266+
raw string
267+
} `json:"-"`
268+
}
269+
270+
// Returns the unmodified JSON received from the API
271+
func (r DiscoveredField) RawJSON() string { return r.JSON.raw }
272+
func (r *DiscoveredField) UnmarshalJSON(data []byte) error {
273+
return apijson.UnmarshalRoot(data, r)
274+
}
275+
276+
// Field type
277+
type DiscoveredFieldType string
278+
279+
const (
280+
DiscoveredFieldTypeText DiscoveredFieldType = "text"
281+
DiscoveredFieldTypeEmail DiscoveredFieldType = "email"
282+
DiscoveredFieldTypePassword DiscoveredFieldType = "password"
283+
DiscoveredFieldTypeTel DiscoveredFieldType = "tel"
284+
DiscoveredFieldTypeNumber DiscoveredFieldType = "number"
285+
DiscoveredFieldTypeURL DiscoveredFieldType = "url"
286+
DiscoveredFieldTypeCode DiscoveredFieldType = "code"
287+
)
288+
289+
type AgentAuthStartParams struct {
290+
// Name of the profile to use for this flow
291+
ProfileName string `json:"profile_name,required"`
292+
// Target domain for authentication
293+
TargetDomain string `json:"target_domain,required"`
294+
// Optional logo URL for the application
295+
AppLogoURL param.Opt[string] `json:"app_logo_url,omitzero" format:"uri"`
296+
// Optional login page URL. If provided, will be stored on the agent and used to
297+
// skip Phase 1 discovery in future invocations.
298+
LoginURL param.Opt[string] `json:"login_url,omitzero" format:"uri"`
299+
// Optional proxy configuration
300+
Proxy AgentAuthStartParamsProxy `json:"proxy,omitzero"`
301+
paramObj
302+
}
303+
304+
func (r AgentAuthStartParams) MarshalJSON() (data []byte, err error) {
305+
type shadow AgentAuthStartParams
306+
return param.MarshalObject(r, (*shadow)(&r))
307+
}
308+
func (r *AgentAuthStartParams) UnmarshalJSON(data []byte) error {
309+
return apijson.UnmarshalRoot(data, r)
310+
}
311+
312+
// Optional proxy configuration
313+
type AgentAuthStartParamsProxy struct {
314+
// ID of the proxy to use
315+
ProxyID param.Opt[string] `json:"proxy_id,omitzero"`
316+
paramObj
317+
}
318+
319+
func (r AgentAuthStartParamsProxy) MarshalJSON() (data []byte, err error) {
320+
type shadow AgentAuthStartParamsProxy
321+
return param.MarshalObject(r, (*shadow)(&r))
322+
}
323+
func (r *AgentAuthStartParamsProxy) UnmarshalJSON(data []byte) error {
324+
return apijson.UnmarshalRoot(data, r)
325+
}

0 commit comments

Comments
 (0)