diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index f81bf99..8305d4a 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.31.0"
+ ".": "0.31.1"
}
\ No newline at end of file
diff --git a/.stats.yml b/.stats.yml
index 91fd3b6..2964321 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 100
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-a6d93dc291278035c96add38bb6150ec2b9ba8bbabb4676e3dbbb8444cf3b1e4.yml
-openapi_spec_hash: 694bcc56d94fd0ff0d1f7b0fc1dae8ba
-config_hash: 62e33cf2ed8fe0b4ceebba63367481ad
+configured_endpoints: 108
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-3fbe762c99e8a120c426ac22bc1fa257c9127d631b12a38a6440a37f52935543.yml
+openapi_spec_hash: 5a190df210ed90b20a71c5061ff43917
+config_hash: 38c9b3b355025daf9bb643040e4af94e
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3bb8760..19d195d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,13 @@
# Changelog
+## 0.31.1 (2026-02-06)
+
+Full Changelog: [v0.31.0...v0.31.1](https://github.com/kernel/kernel-go-sdk/compare/v0.31.0...v0.31.1)
+
+### Chores
+
+* add Managed Auth API planning doc ([fe6c74f](https://github.com/kernel/kernel-go-sdk/commit/fe6c74f86576f1939a61e5ea78a0480837629c81))
+
## 0.31.0 (2026-02-06)
Full Changelog: [v0.30.0...v0.31.0](https://github.com/kernel/kernel-go-sdk/compare/v0.30.0...v0.31.0)
diff --git a/README.md b/README.md
index 467688c..7096145 100644
--- a/README.md
+++ b/README.md
@@ -28,7 +28,7 @@ Or to pin the version:
```sh
-go get -u 'github.com/kernel/kernel-go-sdk@v0.31.0'
+go get -u 'github.com/kernel/kernel-go-sdk@v0.31.1'
```
diff --git a/agentauth.go b/agentauth.go
index f34761d..fb05f0c 100644
--- a/agentauth.go
+++ b/agentauth.go
@@ -43,10 +43,13 @@ func NewAgentAuthService(opts ...option.RequestOption) (r AgentAuthService) {
return
}
-// Creates a new auth agent for the specified domain and profile combination, or
-// returns an existing one if it already exists. This is idempotent - calling with
-// the same domain and profile will return the same agent. Does NOT start an
-// invocation - use POST /agents/auth/invocations to start an auth flow.
+// **Deprecated: Use POST /auth/connections instead.** Creates a new auth agent for
+// the specified domain and profile combination, or returns an existing one if it
+// already exists. This is idempotent - calling with the same domain and profile
+// will return the same agent. Does NOT start an invocation - use POST
+// /agents/auth/invocations to start an auth flow.
+//
+// Deprecated: deprecated
func (r *AgentAuthService) New(ctx context.Context, body AgentAuthNewParams, opts ...option.RequestOption) (res *AuthAgent, err error) {
opts = slices.Concat(r.Options, opts)
path := "agents/auth"
@@ -54,8 +57,10 @@ func (r *AgentAuthService) New(ctx context.Context, body AgentAuthNewParams, opt
return
}
-// Retrieve an auth agent by its ID. Returns the current authentication status of
-// the managed profile.
+// **Deprecated: Use GET /auth/connections/{id} instead.** Retrieve an auth agent
+// by its ID. Returns the current authentication status of the managed profile.
+//
+// Deprecated: deprecated
func (r *AgentAuthService) Get(ctx context.Context, id string, opts ...option.RequestOption) (res *AuthAgent, err error) {
opts = slices.Concat(r.Options, opts)
if id == "" {
@@ -67,7 +72,10 @@ func (r *AgentAuthService) Get(ctx context.Context, id string, opts ...option.Re
return
}
-// List auth agents with optional filters for profile_name and domain.
+// **Deprecated: Use GET /auth/connections instead.** List auth agents with
+// optional filters for profile_name and domain.
+//
+// Deprecated: deprecated
func (r *AgentAuthService) List(ctx context.Context, query AgentAuthListParams, opts ...option.RequestOption) (res *pagination.OffsetPagination[AuthAgent], err error) {
var raw *http.Response
opts = slices.Concat(r.Options, opts)
@@ -85,16 +93,22 @@ func (r *AgentAuthService) List(ctx context.Context, query AgentAuthListParams,
return res, nil
}
-// List auth agents with optional filters for profile_name and domain.
+// **Deprecated: Use GET /auth/connections instead.** List auth agents with
+// optional filters for profile_name and domain.
+//
+// Deprecated: deprecated
func (r *AgentAuthService) ListAutoPaging(ctx context.Context, query AgentAuthListParams, opts ...option.RequestOption) *pagination.OffsetPaginationAutoPager[AuthAgent] {
return pagination.NewOffsetPaginationAutoPager(r.List(ctx, query, opts...))
}
-// Deletes an auth agent and terminates its workflow. This will:
+// **Deprecated: Use DELETE /auth/connections/{id} instead.** Deletes an auth agent
+// and terminates its workflow. This will:
//
// - Soft delete the auth agent record
// - Gracefully terminate the agent's Temporal workflow
// - Cancel any in-progress invocations
+//
+// Deprecated: deprecated
func (r *AgentAuthService) Delete(ctx context.Context, id string, opts ...option.RequestOption) (err error) {
opts = slices.Concat(r.Options, opts)
opts = append([]option.RequestOption{option.WithHeader("Accept", "*/*")}, opts...)
@@ -124,13 +138,12 @@ type AgentAuthInvocationResponse struct {
// Any of "initialized", "discovering", "awaiting_input",
// "awaiting_external_action", "submitting", "completed", "expired".
Step AgentAuthInvocationResponseStep `json:"step,required"`
- // The invocation type:
+ // The session type:
//
- // - login: First-time authentication
- // - reauth: Re-authentication for previously authenticated agents
- // - auto_login: Legacy type (no longer created, kept for backward compatibility)
+ // - login: User-initiated authentication
+ // - reauth: System-triggered re-authentication (via health check)
//
- // Any of "login", "auto_login", "reauth".
+ // Any of "login", "reauth".
Type AgentAuthInvocationResponseType `json:"type,required"`
// Error message explaining why the invocation failed (present when status=FAILED)
ErrorMessage string `json:"error_message,nullable"`
@@ -201,26 +214,24 @@ const (
AgentAuthInvocationResponseStepExpired AgentAuthInvocationResponseStep = "expired"
)
-// The invocation type:
+// The session type:
//
-// - login: First-time authentication
-// - reauth: Re-authentication for previously authenticated agents
-// - auto_login: Legacy type (no longer created, kept for backward compatibility)
+// - login: User-initiated authentication
+// - reauth: System-triggered re-authentication (via health check)
type AgentAuthInvocationResponseType string
const (
- AgentAuthInvocationResponseTypeLogin AgentAuthInvocationResponseType = "login"
- AgentAuthInvocationResponseTypeAutoLogin AgentAuthInvocationResponseType = "auto_login"
- AgentAuthInvocationResponseTypeReauth AgentAuthInvocationResponseType = "reauth"
+ AgentAuthInvocationResponseTypeLogin AgentAuthInvocationResponseType = "login"
+ AgentAuthInvocationResponseTypeReauth AgentAuthInvocationResponseType = "reauth"
)
// An MFA method option for verification
type AgentAuthInvocationResponseMfaOption struct {
// The visible option text
Label string `json:"label,required"`
- // The MFA delivery method type
+ // The MFA delivery method type (includes password for auth method selection pages)
//
- // Any of "sms", "call", "email", "totp", "push", "security_key".
+ // Any of "sms", "call", "email", "totp", "push", "password".
Type string `json:"type,required"`
// Additional instructions from the site
Description string `json:"description,nullable"`
@@ -301,14 +312,34 @@ type AuthAgent struct {
// Additional domains that are valid for this auth agent's authentication flow
// (besides the primary domain). Useful when login pages redirect to different
// domains.
+ //
+ // The following SSO/OAuth provider domains are automatically allowed by default
+ // and do not need to be specified:
+ //
+ // - Google: accounts.google.com
+ // - Microsoft/Azure AD: login.microsoftonline.com, login.live.com
+ // - Okta: _.okta.com, _.oktapreview.com
+ // - Auth0: _.auth0.com, _.us.auth0.com, _.eu.auth0.com, _.au.auth0.com
+ // - Apple: appleid.apple.com
+ // - GitHub: github.com
+ // - Facebook/Meta: www.facebook.com
+ // - LinkedIn: www.linkedin.com
+ // - Amazon Cognito: \*.amazoncognito.com
+ // - OneLogin: \*.onelogin.com
+ // - Ping Identity: _.pingone.com, _.pingidentity.com
AllowedDomains []string `json:"allowed_domains"`
// Whether automatic re-authentication is possible (has credential_id, selectors,
// and login_url)
CanReauth bool `json:"can_reauth"`
- // ID of the linked credential for automatic re-authentication
+ // Reference to credentials for managed auth. Use one of:
+ //
+ // - { name } for Kernel credentials
+ // - { provider, path } for external provider item
+ // - { provider, auto: true } for external provider domain lookup
+ Credential AuthAgentCredential `json:"credential"`
+ // ID of the linked Kernel credential for automatic re-authentication (deprecated,
+ // use credential)
CredentialID string `json:"credential_id"`
- // Name of the linked credential for automatic re-authentication
- CredentialName string `json:"credential_name"`
// Whether this auth agent has stored selectors for deterministic re-authentication
HasSelectors bool `json:"has_selectors"`
// When the last authentication check was performed
@@ -324,8 +355,8 @@ type AuthAgent struct {
Status respjson.Field
AllowedDomains respjson.Field
CanReauth respjson.Field
+ Credential respjson.Field
CredentialID respjson.Field
- CredentialName respjson.Field
HasSelectors respjson.Field
LastAuthCheckAt respjson.Field
PostLoginURL respjson.Field
@@ -348,6 +379,37 @@ const (
AuthAgentStatusNeedsAuth AuthAgentStatus = "NEEDS_AUTH"
)
+// Reference to credentials for managed auth. Use one of:
+//
+// - { name } for Kernel credentials
+// - { provider, path } for external provider item
+// - { provider, auto: true } for external provider domain lookup
+type AuthAgentCredential struct {
+ // If true, lookup by domain from the specified provider
+ Auto bool `json:"auto"`
+ // Kernel credential name
+ Name string `json:"name"`
+ // Provider-specific path (e.g., "VaultName/ItemName" for 1Password)
+ Path string `json:"path"`
+ // External provider name (e.g., "my-1p")
+ Provider string `json:"provider"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ Auto respjson.Field
+ Name respjson.Field
+ Path respjson.Field
+ Provider respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r AuthAgentCredential) RawJSON() string { return r.JSON.raw }
+func (r *AuthAgentCredential) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
// Request to create or find an auth agent
//
// The properties Domain, ProfileName are required.
@@ -366,6 +428,21 @@ type AuthAgentCreateRequestParam struct {
// Additional domains that are valid for this auth agent's authentication flow
// (besides the primary domain). Useful when login pages redirect to different
// domains.
+ //
+ // The following SSO/OAuth provider domains are automatically allowed by default
+ // and do not need to be specified:
+ //
+ // - Google: accounts.google.com
+ // - Microsoft/Azure AD: login.microsoftonline.com, login.live.com
+ // - Okta: _.okta.com, _.oktapreview.com
+ // - Auth0: _.auth0.com, _.us.auth0.com, _.eu.auth0.com, _.au.auth0.com
+ // - Apple: appleid.apple.com
+ // - GitHub: github.com
+ // - Facebook/Meta: www.facebook.com
+ // - LinkedIn: www.linkedin.com
+ // - Amazon Cognito: \*.amazoncognito.com
+ // - OneLogin: \*.onelogin.com
+ // - Ping Identity: _.pingone.com, _.pingidentity.com
AllowedDomains []string `json:"allowed_domains,omitzero"`
// Optional proxy configuration
Proxy AuthAgentCreateRequestProxyParam `json:"proxy,omitzero"`
@@ -426,13 +503,12 @@ type AuthAgentInvocationCreateResponse struct {
HostedURL string `json:"hosted_url,required" format:"uri"`
// Unique identifier for the invocation.
InvocationID string `json:"invocation_id,required"`
- // The invocation type:
+ // The session type:
//
- // - login: First-time authentication
- // - reauth: Re-authentication for previously authenticated agents
- // - auto_login: Legacy type (no longer created, kept for backward compatibility)
+ // - login: User-initiated authentication
+ // - reauth: System-triggered re-authentication (via health check)
//
- // Any of "login", "auto_login", "reauth".
+ // Any of "login", "reauth".
Type AuthAgentInvocationCreateResponseType `json:"type,required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
@@ -452,17 +528,15 @@ func (r *AuthAgentInvocationCreateResponse) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-// The invocation type:
+// The session type:
//
-// - login: First-time authentication
-// - reauth: Re-authentication for previously authenticated agents
-// - auto_login: Legacy type (no longer created, kept for backward compatibility)
+// - login: User-initiated authentication
+// - reauth: System-triggered re-authentication (via health check)
type AuthAgentInvocationCreateResponseType string
const (
- AuthAgentInvocationCreateResponseTypeLogin AuthAgentInvocationCreateResponseType = "login"
- AuthAgentInvocationCreateResponseTypeAutoLogin AuthAgentInvocationCreateResponseType = "auto_login"
- AuthAgentInvocationCreateResponseTypeReauth AuthAgentInvocationCreateResponseType = "reauth"
+ AuthAgentInvocationCreateResponseTypeLogin AuthAgentInvocationCreateResponseType = "login"
+ AuthAgentInvocationCreateResponseTypeReauth AuthAgentInvocationCreateResponseType = "reauth"
)
// A discovered form field
@@ -477,20 +551,26 @@ type DiscoveredField struct {
//
// Any of "text", "email", "password", "tel", "number", "url", "code", "totp".
Type DiscoveredFieldType `json:"type,required"`
+ // If this field is associated with an MFA option, the type of that option (e.g.,
+ // password field linked to "Enter password" option)
+ //
+ // Any of "sms", "call", "email", "totp", "push", "password".
+ LinkedMfaType DiscoveredFieldLinkedMfaType `json:"linked_mfa_type,nullable"`
// Field placeholder
Placeholder string `json:"placeholder"`
// Whether field is required
Required bool `json:"required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
- Label respjson.Field
- Name respjson.Field
- Selector respjson.Field
- Type respjson.Field
- Placeholder respjson.Field
- Required respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
+ Label respjson.Field
+ Name respjson.Field
+ Selector respjson.Field
+ Type respjson.Field
+ LinkedMfaType respjson.Field
+ Placeholder respjson.Field
+ Required respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
} `json:"-"`
}
@@ -514,6 +594,19 @@ const (
DiscoveredFieldTypeTotp DiscoveredFieldType = "totp"
)
+// If this field is associated with an MFA option, the type of that option (e.g.,
+// password field linked to "Enter password" option)
+type DiscoveredFieldLinkedMfaType string
+
+const (
+ DiscoveredFieldLinkedMfaTypeSMS DiscoveredFieldLinkedMfaType = "sms"
+ DiscoveredFieldLinkedMfaTypeCall DiscoveredFieldLinkedMfaType = "call"
+ DiscoveredFieldLinkedMfaTypeEmail DiscoveredFieldLinkedMfaType = "email"
+ DiscoveredFieldLinkedMfaTypeTotp DiscoveredFieldLinkedMfaType = "totp"
+ DiscoveredFieldLinkedMfaTypePush DiscoveredFieldLinkedMfaType = "push"
+ DiscoveredFieldLinkedMfaTypePassword DiscoveredFieldLinkedMfaType = "password"
+)
+
type AgentAuthNewParams struct {
// Request to create or find an auth agent
AuthAgentCreateRequest AuthAgentCreateRequestParam
diff --git a/agentauthinvocation.go b/agentauthinvocation.go
index 91acce7..7226c53 100644
--- a/agentauthinvocation.go
+++ b/agentauthinvocation.go
@@ -37,9 +37,11 @@ func NewAgentAuthInvocationService(opts ...option.RequestOption) (r AgentAuthInv
return
}
-// Creates a new authentication invocation for the specified auth agent. This
-// starts the auth flow and returns a hosted URL for the user to complete
-// authentication.
+// **Deprecated: Use POST /auth/connections/{id}/login instead.** Creates a new
+// authentication invocation for the specified auth agent. This starts the auth
+// flow and returns a hosted URL for the user to complete authentication.
+//
+// Deprecated: deprecated
func (r *AgentAuthInvocationService) New(ctx context.Context, body AgentAuthInvocationNewParams, opts ...option.RequestOption) (res *AuthAgentInvocationCreateResponse, err error) {
opts = slices.Concat(r.Options, opts)
path := "agents/auth/invocations"
@@ -47,8 +49,11 @@ func (r *AgentAuthInvocationService) New(ctx context.Context, body AgentAuthInvo
return
}
-// Returns invocation details including status, app_name, and domain. Supports both
-// API key and JWT (from exchange endpoint) authentication.
+// **Deprecated: Use GET /auth/connections/{id} instead.** Returns invocation
+// details including status, app_name, and domain. Supports both API key and JWT
+// (from exchange endpoint) authentication.
+//
+// Deprecated: deprecated
func (r *AgentAuthInvocationService) Get(ctx context.Context, invocationID string, opts ...option.RequestOption) (res *AgentAuthInvocationResponse, err error) {
opts = slices.Concat(r.Options, opts)
if invocationID == "" {
@@ -60,8 +65,11 @@ func (r *AgentAuthInvocationService) Get(ctx context.Context, invocationID strin
return
}
-// Validates the handoff code and returns a JWT token for subsequent requests. No
-// authentication required (the handoff code serves as the credential).
+// **Deprecated: Use POST /auth/connections/{id}/exchange instead.** Validates the
+// handoff code and returns a JWT token for subsequent requests. No authentication
+// required (the handoff code serves as the credential).
+//
+// Deprecated: deprecated
func (r *AgentAuthInvocationService) Exchange(ctx context.Context, invocationID string, body AgentAuthInvocationExchangeParams, opts ...option.RequestOption) (res *AgentAuthInvocationExchangeResponse, err error) {
opts = slices.Concat(r.Options, opts)
if invocationID == "" {
@@ -73,9 +81,11 @@ func (r *AgentAuthInvocationService) Exchange(ctx context.Context, invocationID
return
}
-// Submits field values for the discovered login form. Returns immediately after
-// submission is accepted. Poll the invocation endpoint to track progress and get
-// results.
+// **Deprecated: Use POST /auth/connections/{id}/submit instead.** Submits field
+// values for the discovered login form. Returns immediately after submission is
+// accepted. Poll the invocation endpoint to track progress and get results.
+//
+// Deprecated: deprecated
func (r *AgentAuthInvocationService) Submit(ctx context.Context, invocationID string, body AgentAuthInvocationSubmitParams, opts ...option.RequestOption) (res *AgentAuthSubmitResponse, err error) {
opts = slices.Concat(r.Options, opts)
if invocationID == "" {
@@ -190,9 +200,9 @@ func (r *AgentAuthInvocationSubmitParamsBodySSOButton) UnmarshalJSON(data []byte
// The property SelectedMfaType is required.
type AgentAuthInvocationSubmitParamsBodySelectedMfaType struct {
- // The MFA delivery method type
+ // The MFA delivery method type (includes password for auth method selection pages)
//
- // Any of "sms", "call", "email", "totp", "push", "security_key".
+ // Any of "sms", "call", "email", "totp", "push", "password".
SelectedMfaType string `json:"selected_mfa_type,omitzero,required"`
paramObj
}
@@ -207,6 +217,6 @@ func (r *AgentAuthInvocationSubmitParamsBodySelectedMfaType) UnmarshalJSON(data
func init() {
apijson.RegisterFieldValidator[AgentAuthInvocationSubmitParamsBodySelectedMfaType](
- "selected_mfa_type", "sms", "call", "email", "totp", "push", "security_key",
+ "selected_mfa_type", "sms", "call", "email", "totp", "push", "password",
)
}
diff --git a/api.md b/api.md
index 0c0e1a9..72fd646 100644
--- a/api.md
+++ b/api.md
@@ -207,6 +207,33 @@ Methods:
- client.Profiles.Delete(ctx context.Context, idOrName string) error
- client.Profiles.Download(ctx context.Context, idOrName string) (\*http.Response, error)
+# Auth
+
+## Connections
+
+Params Types:
+
+- kernel.LoginRequestParam
+- kernel.ManagedAuthCreateRequestParam
+- kernel.SubmitFieldsRequestParam
+
+Response Types:
+
+- kernel.LoginResponse
+- kernel.ManagedAuth
+- kernel.SubmitFieldsResponse
+- kernel.AuthConnectionFollowResponseUnion
+
+Methods:
+
+- client.Auth.Connections.New(ctx context.Context, body kernel.AuthConnectionNewParams) (\*kernel.ManagedAuth, error)
+- client.Auth.Connections.Get(ctx context.Context, id string) (\*kernel.ManagedAuth, error)
+- client.Auth.Connections.List(ctx context.Context, query kernel.AuthConnectionListParams) (\*pagination.OffsetPagination[kernel.ManagedAuth], error)
+- client.Auth.Connections.Delete(ctx context.Context, id string) error
+- client.Auth.Connections.Follow(ctx context.Context, id string) (\*kernel.AuthConnectionFollowResponseUnion, error)
+- client.Auth.Connections.Login(ctx context.Context, id string, body kernel.AuthConnectionLoginParams) (\*kernel.LoginResponse, error)
+- client.Auth.Connections.Submit(ctx context.Context, id string, body kernel.AuthConnectionSubmitParams) (\*kernel.SubmitFieldsResponse, error)
+
# Proxies
Response Types:
@@ -325,13 +352,16 @@ Params Types:
Response Types:
- kernel.CredentialProvider
+- kernel.CredentialProviderItem
- kernel.CredentialProviderTestResult
+- kernel.CredentialProviderListItemsResponse
Methods:
-- client.CredentialProviders.New(ctx context.Context, body kernel.CredentialProviderNewParams) (\*kernel.CredentialProvider, error)
-- client.CredentialProviders.Get(ctx context.Context, id string) (\*kernel.CredentialProvider, error)
-- client.CredentialProviders.Update(ctx context.Context, id string, body kernel.CredentialProviderUpdateParams) (\*kernel.CredentialProvider, error)
-- client.CredentialProviders.List(ctx context.Context) (\*[]kernel.CredentialProvider, error)
-- client.CredentialProviders.Delete(ctx context.Context, id string) error
-- client.CredentialProviders.Test(ctx context.Context, id string) (\*kernel.CredentialProviderTestResult, error)
+- client.CredentialProviders.New(ctx context.Context, body kernel.CredentialProviderNewParams) (\*kernel.CredentialProvider, error)
+- client.CredentialProviders.Get(ctx context.Context, id string) (\*kernel.CredentialProvider, error)
+- client.CredentialProviders.Update(ctx context.Context, id string, body kernel.CredentialProviderUpdateParams) (\*kernel.CredentialProvider, error)
+- client.CredentialProviders.List(ctx context.Context) (\*[]kernel.CredentialProvider, error)
+- client.CredentialProviders.Delete(ctx context.Context, id string) error
+- client.CredentialProviders.ListItems(ctx context.Context, id string) (\*kernel.CredentialProviderListItemsResponse, error)
+- client.CredentialProviders.Test(ctx context.Context, id string) (\*kernel.CredentialProviderTestResult, error)
diff --git a/auth.go b/auth.go
new file mode 100644
index 0000000..0469989
--- /dev/null
+++ b/auth.go
@@ -0,0 +1,28 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+package kernel
+
+import (
+ "github.com/kernel/kernel-go-sdk/option"
+)
+
+// AuthService contains methods and other services that help with interacting with
+// the kernel API.
+//
+// Note, unlike clients, this service does not read variables from the environment
+// automatically. You should not instantiate this service directly, and instead use
+// the [NewAuthService] method instead.
+type AuthService struct {
+ Options []option.RequestOption
+ Connections AuthConnectionService
+}
+
+// NewAuthService generates a new service that applies the given options to each
+// request. These options are applied after the parent client's options (if there
+// is one), and before any request-specific options.
+func NewAuthService(opts ...option.RequestOption) (r AuthService) {
+ r = AuthService{}
+ r.Options = opts
+ r.Connections = NewAuthConnectionService(opts...)
+ return
+}
diff --git a/authconnection.go b/authconnection.go
new file mode 100644
index 0000000..6d7a9aa
--- /dev/null
+++ b/authconnection.go
@@ -0,0 +1,878 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+package kernel
+
+import (
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "net/http"
+ "net/url"
+ "slices"
+ "time"
+
+ "github.com/kernel/kernel-go-sdk/internal/apijson"
+ "github.com/kernel/kernel-go-sdk/internal/apiquery"
+ shimjson "github.com/kernel/kernel-go-sdk/internal/encoding/json"
+ "github.com/kernel/kernel-go-sdk/internal/requestconfig"
+ "github.com/kernel/kernel-go-sdk/option"
+ "github.com/kernel/kernel-go-sdk/packages/pagination"
+ "github.com/kernel/kernel-go-sdk/packages/param"
+ "github.com/kernel/kernel-go-sdk/packages/respjson"
+ "github.com/kernel/kernel-go-sdk/packages/ssestream"
+ "github.com/kernel/kernel-go-sdk/shared"
+ "github.com/kernel/kernel-go-sdk/shared/constant"
+)
+
+// AuthConnectionService contains methods and other services that help with
+// interacting with the kernel API.
+//
+// Note, unlike clients, this service does not read variables from the environment
+// automatically. You should not instantiate this service directly, and instead use
+// the [NewAuthConnectionService] method instead.
+type AuthConnectionService struct {
+ Options []option.RequestOption
+}
+
+// NewAuthConnectionService generates a new service that applies the given options
+// to each request. These options are applied after the parent client's options (if
+// there is one), and before any request-specific options.
+func NewAuthConnectionService(opts ...option.RequestOption) (r AuthConnectionService) {
+ r = AuthConnectionService{}
+ r.Options = opts
+ return
+}
+
+// Creates managed authentication for a profile and domain combination. Returns 409
+// Conflict if managed auth already exists for the given profile and domain.
+func (r *AuthConnectionService) New(ctx context.Context, body AuthConnectionNewParams, opts ...option.RequestOption) (res *ManagedAuth, err error) {
+ opts = slices.Concat(r.Options, opts)
+ path := "auth/connections"
+ err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...)
+ return
+}
+
+// Retrieve managed auth by its ID. Includes current flow state if a login is in
+// progress.
+func (r *AuthConnectionService) Get(ctx context.Context, id string, opts ...option.RequestOption) (res *ManagedAuth, err error) {
+ opts = slices.Concat(r.Options, opts)
+ if id == "" {
+ err = errors.New("missing required id parameter")
+ return
+ }
+ path := fmt.Sprintf("auth/connections/%s", id)
+ err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...)
+ return
+}
+
+// List managed auths with optional filters for profile_name and domain.
+func (r *AuthConnectionService) List(ctx context.Context, query AuthConnectionListParams, opts ...option.RequestOption) (res *pagination.OffsetPagination[ManagedAuth], err error) {
+ var raw *http.Response
+ opts = slices.Concat(r.Options, opts)
+ opts = append([]option.RequestOption{option.WithResponseInto(&raw)}, opts...)
+ path := "auth/connections"
+ cfg, err := requestconfig.NewRequestConfig(ctx, http.MethodGet, path, query, &res, opts...)
+ if err != nil {
+ return nil, err
+ }
+ err = cfg.Execute()
+ if err != nil {
+ return nil, err
+ }
+ res.SetPageConfig(cfg, raw)
+ return res, nil
+}
+
+// List managed auths with optional filters for profile_name and domain.
+func (r *AuthConnectionService) ListAutoPaging(ctx context.Context, query AuthConnectionListParams, opts ...option.RequestOption) *pagination.OffsetPaginationAutoPager[ManagedAuth] {
+ return pagination.NewOffsetPaginationAutoPager(r.List(ctx, query, opts...))
+}
+
+// Deletes managed auth and terminates its workflow. This will:
+//
+// - Delete the managed auth record
+// - Terminate the Temporal workflow
+// - Cancel any in-progress login flows
+func (r *AuthConnectionService) Delete(ctx context.Context, id string, opts ...option.RequestOption) (err error) {
+ opts = slices.Concat(r.Options, opts)
+ opts = append([]option.RequestOption{option.WithHeader("Accept", "*/*")}, opts...)
+ if id == "" {
+ err = errors.New("missing required id parameter")
+ return
+ }
+ path := fmt.Sprintf("auth/connections/%s", id)
+ err = requestconfig.ExecuteNewRequest(ctx, http.MethodDelete, path, nil, nil, opts...)
+ return
+}
+
+// Establishes a Server-Sent Events (SSE) stream that delivers real-time login flow
+// state updates. The stream terminates automatically once the flow reaches a
+// terminal state (SUCCESS, FAILED, EXPIRED, CANCELED).
+func (r *AuthConnectionService) FollowStreaming(ctx context.Context, id string, opts ...option.RequestOption) (stream *ssestream.Stream[AuthConnectionFollowResponseUnion]) {
+ var (
+ raw *http.Response
+ err error
+ )
+ opts = slices.Concat(r.Options, opts)
+ opts = append([]option.RequestOption{option.WithHeader("Accept", "text/event-stream")}, opts...)
+ if id == "" {
+ err = errors.New("missing required id parameter")
+ return
+ }
+ path := fmt.Sprintf("auth/connections/%s/events", id)
+ err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &raw, opts...)
+ return ssestream.NewStream[AuthConnectionFollowResponseUnion](ssestream.NewDecoder(raw), err)
+}
+
+// Starts a login flow for the managed auth. Returns immediately with a hosted URL
+// for the user to complete authentication, or triggers automatic re-auth if
+// credentials are stored.
+func (r *AuthConnectionService) Login(ctx context.Context, id string, body AuthConnectionLoginParams, opts ...option.RequestOption) (res *LoginResponse, err error) {
+ opts = slices.Concat(r.Options, opts)
+ if id == "" {
+ err = errors.New("missing required id parameter")
+ return
+ }
+ path := fmt.Sprintf("auth/connections/%s/login", id)
+ err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...)
+ return
+}
+
+// Submits field values for the login form. Poll the managed auth to track progress
+// and get results.
+func (r *AuthConnectionService) Submit(ctx context.Context, id string, body AuthConnectionSubmitParams, opts ...option.RequestOption) (res *SubmitFieldsResponse, err error) {
+ opts = slices.Concat(r.Options, opts)
+ if id == "" {
+ err = errors.New("missing required id parameter")
+ return
+ }
+ path := fmt.Sprintf("auth/connections/%s/submit", id)
+ err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...)
+ return
+}
+
+// Request to start a login flow
+type LoginRequestParam struct {
+ // If provided, saves credentials under this name upon successful login
+ SaveCredentialAs param.Opt[string] `json:"save_credential_as,omitzero"`
+ paramObj
+}
+
+func (r LoginRequestParam) MarshalJSON() (data []byte, err error) {
+ type shadow LoginRequestParam
+ return param.MarshalObject(r, (*shadow)(&r))
+}
+func (r *LoginRequestParam) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+// Response from starting a login flow
+type LoginResponse struct {
+ // Managed auth ID
+ ID string `json:"id,required"`
+ // When the login flow expires
+ FlowExpiresAt time.Time `json:"flow_expires_at,required" format:"date-time"`
+ // Type of login flow started
+ //
+ // Any of "LOGIN", "REAUTH".
+ FlowType LoginResponseFlowType `json:"flow_type,required"`
+ // URL to redirect user to for login
+ HostedURL string `json:"hosted_url,required" format:"uri"`
+ // One-time code for handoff (internal use)
+ HandoffCode string `json:"handoff_code"`
+ // Browser live view URL for watching the login flow
+ LiveViewURL string `json:"live_view_url" format:"uri"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ ID respjson.Field
+ FlowExpiresAt respjson.Field
+ FlowType respjson.Field
+ HostedURL respjson.Field
+ HandoffCode respjson.Field
+ LiveViewURL respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r LoginResponse) RawJSON() string { return r.JSON.raw }
+func (r *LoginResponse) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+// Type of login flow started
+type LoginResponseFlowType string
+
+const (
+ LoginResponseFlowTypeLogin LoginResponseFlowType = "LOGIN"
+ LoginResponseFlowTypeReauth LoginResponseFlowType = "REAUTH"
+)
+
+// Managed authentication that keeps a profile logged into a specific domain. Flow
+// fields (flow_status, flow_step, discovered_fields, mfa_options) reflect the most
+// recent login flow and are null when no flow has been initiated.
+type ManagedAuth struct {
+ // Unique identifier for the managed auth
+ ID string `json:"id,required"`
+ // Target domain for authentication
+ Domain string `json:"domain,required"`
+ // Name of the profile associated with this managed auth
+ ProfileName string `json:"profile_name,required"`
+ // Current authentication status of the managed profile
+ //
+ // Any of "AUTHENTICATED", "NEEDS_AUTH".
+ Status ManagedAuthStatus `json:"status,required"`
+ // Additional domains that are valid for this auth flow (besides the primary
+ // domain). Useful when login pages redirect to different domains.
+ //
+ // The following SSO/OAuth provider domains are automatically allowed by default
+ // and do not need to be specified:
+ //
+ // - Google: accounts.google.com
+ // - Microsoft/Azure AD: login.microsoftonline.com, login.live.com
+ // - Okta: _.okta.com, _.oktapreview.com
+ // - Auth0: _.auth0.com, _.us.auth0.com, _.eu.auth0.com, _.au.auth0.com
+ // - Apple: appleid.apple.com
+ // - GitHub: github.com
+ // - Facebook/Meta: www.facebook.com
+ // - LinkedIn: www.linkedin.com
+ // - Amazon Cognito: \*.amazoncognito.com
+ // - OneLogin: \*.onelogin.com
+ // - Ping Identity: _.pingone.com, _.pingidentity.com
+ AllowedDomains []string `json:"allowed_domains"`
+ // Whether automatic re-authentication is possible (has credential, selectors, and
+ // login_url)
+ CanReauth bool `json:"can_reauth"`
+ // Reference to credentials for managed auth. Use one of:
+ //
+ // - { name } for Kernel credentials
+ // - { provider, path } for external provider item
+ // - { provider, auto: true } for external provider domain lookup
+ Credential ManagedAuthCredential `json:"credential"`
+ // Fields awaiting input (present when flow_step=awaiting_input)
+ DiscoveredFields []DiscoveredField `json:"discovered_fields,nullable"`
+ // Error message (present when flow_status=failed)
+ ErrorMessage string `json:"error_message,nullable"`
+ // Instructions for external action (present when
+ // flow_step=awaiting_external_action)
+ ExternalActionMessage string `json:"external_action_message,nullable"`
+ // When the current flow expires (null when no flow in progress)
+ FlowExpiresAt time.Time `json:"flow_expires_at,nullable" format:"date-time"`
+ // Current flow status (null when no flow in progress)
+ //
+ // Any of "IN_PROGRESS", "SUCCESS", "FAILED", "EXPIRED", "CANCELED".
+ FlowStatus ManagedAuthFlowStatus `json:"flow_status,nullable"`
+ // Current step in the flow (null when no flow in progress)
+ //
+ // Any of "DISCOVERING", "AWAITING_INPUT", "AWAITING_EXTERNAL_ACTION",
+ // "SUBMITTING", "COMPLETED".
+ FlowStep ManagedAuthFlowStep `json:"flow_step,nullable"`
+ // Type of the current flow (null when no flow in progress)
+ //
+ // Any of "LOGIN", "REAUTH".
+ FlowType ManagedAuthFlowType `json:"flow_type,nullable"`
+ // Interval in seconds between automatic health checks. When set, the system
+ // periodically verifies the authentication status and triggers re-authentication
+ // if needed. Must be between 300 (5 minutes) and 86400 (24 hours). Default is 3600
+ // (1 hour).
+ HealthCheckInterval int64 `json:"health_check_interval,nullable"`
+ // URL to redirect user to for hosted login (present when flow in progress)
+ HostedURL string `json:"hosted_url,nullable" format:"uri"`
+ // When the profile was last successfully authenticated
+ LastAuthAt time.Time `json:"last_auth_at" format:"date-time"`
+ // Browser live view URL for debugging (present when flow in progress)
+ LiveViewURL string `json:"live_view_url,nullable" format:"uri"`
+ // MFA method options (present when flow_step=awaiting_input and MFA selection
+ // required)
+ MfaOptions []ManagedAuthMfaOption `json:"mfa_options,nullable"`
+ // SSO buttons available (present when flow_step=awaiting_input)
+ PendingSSOButtons []ManagedAuthPendingSSOButton `json:"pending_sso_buttons,nullable"`
+ // URL where the browser landed after successful login
+ PostLoginURL string `json:"post_login_url" format:"uri"`
+ // SSO provider being used (e.g., google, github, microsoft)
+ SSOProvider string `json:"sso_provider,nullable"`
+ // Visible error message from the website (e.g., 'Incorrect password'). Present
+ // when the website displays an error during login.
+ WebsiteError string `json:"website_error,nullable"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ ID respjson.Field
+ Domain respjson.Field
+ ProfileName respjson.Field
+ Status respjson.Field
+ AllowedDomains respjson.Field
+ CanReauth respjson.Field
+ Credential respjson.Field
+ DiscoveredFields respjson.Field
+ ErrorMessage respjson.Field
+ ExternalActionMessage respjson.Field
+ FlowExpiresAt respjson.Field
+ FlowStatus respjson.Field
+ FlowStep respjson.Field
+ FlowType respjson.Field
+ HealthCheckInterval respjson.Field
+ HostedURL respjson.Field
+ LastAuthAt respjson.Field
+ LiveViewURL respjson.Field
+ MfaOptions respjson.Field
+ PendingSSOButtons respjson.Field
+ PostLoginURL respjson.Field
+ SSOProvider respjson.Field
+ WebsiteError respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r ManagedAuth) RawJSON() string { return r.JSON.raw }
+func (r *ManagedAuth) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+// Current authentication status of the managed profile
+type ManagedAuthStatus string
+
+const (
+ ManagedAuthStatusAuthenticated ManagedAuthStatus = "AUTHENTICATED"
+ ManagedAuthStatusNeedsAuth ManagedAuthStatus = "NEEDS_AUTH"
+)
+
+// Reference to credentials for managed auth. Use one of:
+//
+// - { name } for Kernel credentials
+// - { provider, path } for external provider item
+// - { provider, auto: true } for external provider domain lookup
+type ManagedAuthCredential struct {
+ // If true, lookup by domain from the specified provider
+ Auto bool `json:"auto"`
+ // Kernel credential name
+ Name string `json:"name"`
+ // Provider-specific path (e.g., "VaultName/ItemName" for 1Password)
+ Path string `json:"path"`
+ // External provider name (e.g., "my-1p")
+ Provider string `json:"provider"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ Auto respjson.Field
+ Name respjson.Field
+ Path respjson.Field
+ Provider respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r ManagedAuthCredential) RawJSON() string { return r.JSON.raw }
+func (r *ManagedAuthCredential) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+// Current flow status (null when no flow in progress)
+type ManagedAuthFlowStatus string
+
+const (
+ ManagedAuthFlowStatusInProgress ManagedAuthFlowStatus = "IN_PROGRESS"
+ ManagedAuthFlowStatusSuccess ManagedAuthFlowStatus = "SUCCESS"
+ ManagedAuthFlowStatusFailed ManagedAuthFlowStatus = "FAILED"
+ ManagedAuthFlowStatusExpired ManagedAuthFlowStatus = "EXPIRED"
+ ManagedAuthFlowStatusCanceled ManagedAuthFlowStatus = "CANCELED"
+)
+
+// Current step in the flow (null when no flow in progress)
+type ManagedAuthFlowStep string
+
+const (
+ ManagedAuthFlowStepDiscovering ManagedAuthFlowStep = "DISCOVERING"
+ ManagedAuthFlowStepAwaitingInput ManagedAuthFlowStep = "AWAITING_INPUT"
+ ManagedAuthFlowStepAwaitingExternalAction ManagedAuthFlowStep = "AWAITING_EXTERNAL_ACTION"
+ ManagedAuthFlowStepSubmitting ManagedAuthFlowStep = "SUBMITTING"
+ ManagedAuthFlowStepCompleted ManagedAuthFlowStep = "COMPLETED"
+)
+
+// Type of the current flow (null when no flow in progress)
+type ManagedAuthFlowType string
+
+const (
+ ManagedAuthFlowTypeLogin ManagedAuthFlowType = "LOGIN"
+ ManagedAuthFlowTypeReauth ManagedAuthFlowType = "REAUTH"
+)
+
+// An MFA method option for verification
+type ManagedAuthMfaOption struct {
+ // The visible option text
+ Label string `json:"label,required"`
+ // The MFA delivery method type (includes password for auth method selection pages)
+ //
+ // Any of "sms", "call", "email", "totp", "push", "password".
+ Type string `json:"type,required"`
+ // Additional instructions from the site
+ Description string `json:"description,nullable"`
+ // The masked destination (phone/email) if shown
+ Target string `json:"target,nullable"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ Label respjson.Field
+ Type respjson.Field
+ Description respjson.Field
+ Target respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r ManagedAuthMfaOption) RawJSON() string { return r.JSON.raw }
+func (r *ManagedAuthMfaOption) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+// An SSO button for signing in with an external identity provider
+type ManagedAuthPendingSSOButton struct {
+ // Visible button text
+ Label string `json:"label,required"`
+ // Identity provider name
+ Provider string `json:"provider,required"`
+ // XPath selector for the button
+ Selector string `json:"selector,required"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ Label respjson.Field
+ Provider respjson.Field
+ Selector respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r ManagedAuthPendingSSOButton) RawJSON() string { return r.JSON.raw }
+func (r *ManagedAuthPendingSSOButton) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+// Request to create managed auth for a profile and domain
+//
+// The properties Domain, ProfileName are required.
+type ManagedAuthCreateRequestParam struct {
+ // Domain for authentication
+ Domain string `json:"domain,required"`
+ // Name of the profile to manage authentication for
+ ProfileName string `json:"profile_name,required"`
+ // Interval in seconds between automatic health checks. When set, the system
+ // periodically verifies the authentication status and triggers re-authentication
+ // if needed. Must be between 300 (5 minutes) and 86400 (24 hours). Default is 3600
+ // (1 hour).
+ HealthCheckInterval param.Opt[int64] `json:"health_check_interval,omitzero"`
+ // Optional login page URL to skip discovery
+ LoginURL param.Opt[string] `json:"login_url,omitzero" format:"uri"`
+ // Additional domains valid for this auth flow (besides the primary domain). Useful
+ // when login pages redirect to different domains.
+ //
+ // The following SSO/OAuth provider domains are automatically allowed by default
+ // and do not need to be specified:
+ //
+ // - Google: accounts.google.com
+ // - Microsoft/Azure AD: login.microsoftonline.com, login.live.com
+ // - Okta: _.okta.com, _.oktapreview.com
+ // - Auth0: _.auth0.com, _.us.auth0.com, _.eu.auth0.com, _.au.auth0.com
+ // - Apple: appleid.apple.com
+ // - GitHub: github.com
+ // - Facebook/Meta: www.facebook.com
+ // - LinkedIn: www.linkedin.com
+ // - Amazon Cognito: \*.amazoncognito.com
+ // - OneLogin: \*.onelogin.com
+ // - Ping Identity: _.pingone.com, _.pingidentity.com
+ AllowedDomains []string `json:"allowed_domains,omitzero"`
+ // Reference to credentials for managed auth. Use one of:
+ //
+ // - { name } for Kernel credentials
+ // - { provider, path } for external provider item
+ // - { provider, auto: true } for external provider domain lookup
+ Credential ManagedAuthCreateRequestCredentialParam `json:"credential,omitzero"`
+ // Optional proxy configuration
+ Proxy ManagedAuthCreateRequestProxyParam `json:"proxy,omitzero"`
+ paramObj
+}
+
+func (r ManagedAuthCreateRequestParam) MarshalJSON() (data []byte, err error) {
+ type shadow ManagedAuthCreateRequestParam
+ return param.MarshalObject(r, (*shadow)(&r))
+}
+func (r *ManagedAuthCreateRequestParam) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+// Reference to credentials for managed auth. Use one of:
+//
+// - { name } for Kernel credentials
+// - { provider, path } for external provider item
+// - { provider, auto: true } for external provider domain lookup
+type ManagedAuthCreateRequestCredentialParam struct {
+ // If true, lookup by domain from the specified provider
+ Auto param.Opt[bool] `json:"auto,omitzero"`
+ // Kernel credential name
+ Name param.Opt[string] `json:"name,omitzero"`
+ // Provider-specific path (e.g., "VaultName/ItemName" for 1Password)
+ Path param.Opt[string] `json:"path,omitzero"`
+ // External provider name (e.g., "my-1p")
+ Provider param.Opt[string] `json:"provider,omitzero"`
+ paramObj
+}
+
+func (r ManagedAuthCreateRequestCredentialParam) MarshalJSON() (data []byte, err error) {
+ type shadow ManagedAuthCreateRequestCredentialParam
+ return param.MarshalObject(r, (*shadow)(&r))
+}
+func (r *ManagedAuthCreateRequestCredentialParam) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+// Optional proxy configuration
+type ManagedAuthCreateRequestProxyParam struct {
+ // ID of the proxy to use
+ ProxyID param.Opt[string] `json:"proxy_id,omitzero"`
+ paramObj
+}
+
+func (r ManagedAuthCreateRequestProxyParam) MarshalJSON() (data []byte, err error) {
+ type shadow ManagedAuthCreateRequestProxyParam
+ return param.MarshalObject(r, (*shadow)(&r))
+}
+func (r *ManagedAuthCreateRequestProxyParam) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+// Request to submit field values for login
+//
+// The property Fields is required.
+type SubmitFieldsRequestParam struct {
+ // Map of field name to value
+ Fields map[string]string `json:"fields,omitzero,required"`
+ // Optional MFA option ID if user selected an MFA method
+ MfaOptionID param.Opt[string] `json:"mfa_option_id,omitzero"`
+ // Optional XPath selector if user chose to click an SSO button instead
+ SSOButtonSelector param.Opt[string] `json:"sso_button_selector,omitzero"`
+ paramObj
+}
+
+func (r SubmitFieldsRequestParam) MarshalJSON() (data []byte, err error) {
+ type shadow SubmitFieldsRequestParam
+ return param.MarshalObject(r, (*shadow)(&r))
+}
+func (r *SubmitFieldsRequestParam) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+// Response from submitting field values
+type SubmitFieldsResponse struct {
+ // Whether the submission was accepted for processing
+ Accepted bool `json:"accepted,required"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ Accepted respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r SubmitFieldsResponse) RawJSON() string { return r.JSON.raw }
+func (r *SubmitFieldsResponse) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+// AuthConnectionFollowResponseUnion contains all possible properties and values
+// from [AuthConnectionFollowResponseManagedAuthState], [shared.ErrorEvent],
+// [shared.HeartbeatEvent].
+//
+// Use the [AuthConnectionFollowResponseUnion.AsAny] method to switch on the
+// variant.
+//
+// Use the methods beginning with 'As' to cast the union to one of its variants.
+type AuthConnectionFollowResponseUnion struct {
+ // Any of "managed_auth_state", "error", "sse_heartbeat".
+ Event string `json:"event"`
+ // This field is from variant [AuthConnectionFollowResponseManagedAuthState].
+ FlowStatus string `json:"flow_status"`
+ // This field is from variant [AuthConnectionFollowResponseManagedAuthState].
+ FlowStep string `json:"flow_step"`
+ Timestamp time.Time `json:"timestamp"`
+ // This field is from variant [AuthConnectionFollowResponseManagedAuthState].
+ DiscoveredFields []DiscoveredField `json:"discovered_fields"`
+ // This field is from variant [AuthConnectionFollowResponseManagedAuthState].
+ ErrorMessage string `json:"error_message"`
+ // This field is from variant [AuthConnectionFollowResponseManagedAuthState].
+ ExternalActionMessage string `json:"external_action_message"`
+ // This field is from variant [AuthConnectionFollowResponseManagedAuthState].
+ FlowType string `json:"flow_type"`
+ // This field is from variant [AuthConnectionFollowResponseManagedAuthState].
+ HostedURL string `json:"hosted_url"`
+ // This field is from variant [AuthConnectionFollowResponseManagedAuthState].
+ LiveViewURL string `json:"live_view_url"`
+ // This field is from variant [AuthConnectionFollowResponseManagedAuthState].
+ MfaOptions []AuthConnectionFollowResponseManagedAuthStateMfaOption `json:"mfa_options"`
+ // This field is from variant [AuthConnectionFollowResponseManagedAuthState].
+ PendingSSOButtons []AuthConnectionFollowResponseManagedAuthStatePendingSSOButton `json:"pending_sso_buttons"`
+ // This field is from variant [AuthConnectionFollowResponseManagedAuthState].
+ PostLoginURL string `json:"post_login_url"`
+ // This field is from variant [AuthConnectionFollowResponseManagedAuthState].
+ WebsiteError string `json:"website_error"`
+ // This field is from variant [shared.ErrorEvent].
+ Error shared.ErrorModel `json:"error"`
+ JSON struct {
+ Event respjson.Field
+ FlowStatus respjson.Field
+ FlowStep respjson.Field
+ Timestamp respjson.Field
+ DiscoveredFields respjson.Field
+ ErrorMessage respjson.Field
+ ExternalActionMessage respjson.Field
+ FlowType respjson.Field
+ HostedURL respjson.Field
+ LiveViewURL respjson.Field
+ MfaOptions respjson.Field
+ PendingSSOButtons respjson.Field
+ PostLoginURL respjson.Field
+ WebsiteError respjson.Field
+ Error respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// anyAuthConnectionFollowResponse is implemented by each variant of
+// [AuthConnectionFollowResponseUnion] to add type safety for the return type of
+// [AuthConnectionFollowResponseUnion.AsAny]
+type anyAuthConnectionFollowResponse interface {
+ ImplAuthConnectionFollowResponseUnion()
+}
+
+func (AuthConnectionFollowResponseManagedAuthState) ImplAuthConnectionFollowResponseUnion() {}
+
+// Use the following switch statement to find the correct variant
+//
+// switch variant := AuthConnectionFollowResponseUnion.AsAny().(type) {
+// case kernel.AuthConnectionFollowResponseManagedAuthState:
+// case shared.ErrorEvent:
+// case shared.HeartbeatEvent:
+// default:
+// fmt.Errorf("no variant present")
+// }
+func (u AuthConnectionFollowResponseUnion) AsAny() anyAuthConnectionFollowResponse {
+ switch u.Event {
+ case "managed_auth_state":
+ return u.AsManagedAuthState()
+ case "error":
+ return u.AsError()
+ case "sse_heartbeat":
+ return u.AsSseHeartbeat()
+ }
+ return nil
+}
+
+func (u AuthConnectionFollowResponseUnion) AsManagedAuthState() (v AuthConnectionFollowResponseManagedAuthState) {
+ apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v)
+ return
+}
+
+func (u AuthConnectionFollowResponseUnion) AsError() (v shared.ErrorEvent) {
+ apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v)
+ return
+}
+
+func (u AuthConnectionFollowResponseUnion) AsSseHeartbeat() (v shared.HeartbeatEvent) {
+ apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v)
+ return
+}
+
+// Returns the unmodified JSON received from the API
+func (u AuthConnectionFollowResponseUnion) RawJSON() string { return u.JSON.raw }
+
+func (r *AuthConnectionFollowResponseUnion) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+// An event representing the current state of a managed auth flow.
+type AuthConnectionFollowResponseManagedAuthState struct {
+ // Event type identifier (always "managed_auth_state").
+ Event constant.ManagedAuthState `json:"event,required"`
+ // Current flow status.
+ //
+ // Any of "IN_PROGRESS", "SUCCESS", "FAILED", "EXPIRED", "CANCELED".
+ FlowStatus string `json:"flow_status,required"`
+ // Current step in the flow.
+ //
+ // Any of "DISCOVERING", "AWAITING_INPUT", "AWAITING_EXTERNAL_ACTION",
+ // "SUBMITTING", "COMPLETED".
+ FlowStep string `json:"flow_step,required"`
+ // Time the state was reported.
+ Timestamp time.Time `json:"timestamp,required" format:"date-time"`
+ // Fields awaiting input (present when flow_step=AWAITING_INPUT).
+ DiscoveredFields []DiscoveredField `json:"discovered_fields"`
+ // Error message (present when flow_status=FAILED).
+ ErrorMessage string `json:"error_message"`
+ // Instructions for external action (present when
+ // flow_step=AWAITING_EXTERNAL_ACTION).
+ ExternalActionMessage string `json:"external_action_message"`
+ // Type of the current flow.
+ //
+ // Any of "LOGIN", "REAUTH".
+ FlowType string `json:"flow_type"`
+ // URL to redirect user to for hosted login.
+ HostedURL string `json:"hosted_url" format:"uri"`
+ // Browser live view URL for debugging.
+ LiveViewURL string `json:"live_view_url" format:"uri"`
+ // MFA method options (present when flow_step=AWAITING_INPUT and MFA selection
+ // required).
+ MfaOptions []AuthConnectionFollowResponseManagedAuthStateMfaOption `json:"mfa_options"`
+ // SSO buttons available (present when flow_step=AWAITING_INPUT).
+ PendingSSOButtons []AuthConnectionFollowResponseManagedAuthStatePendingSSOButton `json:"pending_sso_buttons"`
+ // URL where the browser landed after successful login.
+ PostLoginURL string `json:"post_login_url" format:"uri"`
+ // Visible error message from the website (e.g., 'Incorrect password'). Present
+ // when the website displays an error during login.
+ WebsiteError string `json:"website_error"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ Event respjson.Field
+ FlowStatus respjson.Field
+ FlowStep respjson.Field
+ Timestamp respjson.Field
+ DiscoveredFields respjson.Field
+ ErrorMessage respjson.Field
+ ExternalActionMessage respjson.Field
+ FlowType respjson.Field
+ HostedURL respjson.Field
+ LiveViewURL respjson.Field
+ MfaOptions respjson.Field
+ PendingSSOButtons respjson.Field
+ PostLoginURL respjson.Field
+ WebsiteError respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r AuthConnectionFollowResponseManagedAuthState) RawJSON() string { return r.JSON.raw }
+func (r *AuthConnectionFollowResponseManagedAuthState) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+// An MFA method option for verification
+type AuthConnectionFollowResponseManagedAuthStateMfaOption struct {
+ // The visible option text
+ Label string `json:"label,required"`
+ // The MFA delivery method type (includes password for auth method selection pages)
+ //
+ // Any of "sms", "call", "email", "totp", "push", "password".
+ Type string `json:"type,required"`
+ // Additional instructions from the site
+ Description string `json:"description,nullable"`
+ // The masked destination (phone/email) if shown
+ Target string `json:"target,nullable"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ Label respjson.Field
+ Type respjson.Field
+ Description respjson.Field
+ Target respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r AuthConnectionFollowResponseManagedAuthStateMfaOption) RawJSON() string { return r.JSON.raw }
+func (r *AuthConnectionFollowResponseManagedAuthStateMfaOption) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+// An SSO button for signing in with an external identity provider
+type AuthConnectionFollowResponseManagedAuthStatePendingSSOButton struct {
+ // Visible button text
+ Label string `json:"label,required"`
+ // Identity provider name
+ Provider string `json:"provider,required"`
+ // XPath selector for the button
+ Selector string `json:"selector,required"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ Label respjson.Field
+ Provider respjson.Field
+ Selector respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r AuthConnectionFollowResponseManagedAuthStatePendingSSOButton) RawJSON() string {
+ return r.JSON.raw
+}
+func (r *AuthConnectionFollowResponseManagedAuthStatePendingSSOButton) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+type AuthConnectionNewParams struct {
+ // Request to create managed auth for a profile and domain
+ ManagedAuthCreateRequest ManagedAuthCreateRequestParam
+ paramObj
+}
+
+func (r AuthConnectionNewParams) MarshalJSON() (data []byte, err error) {
+ return shimjson.Marshal(r.ManagedAuthCreateRequest)
+}
+func (r *AuthConnectionNewParams) UnmarshalJSON(data []byte) error {
+ return json.Unmarshal(data, &r.ManagedAuthCreateRequest)
+}
+
+type AuthConnectionListParams struct {
+ // Filter by domain
+ Domain param.Opt[string] `query:"domain,omitzero" json:"-"`
+ // Maximum number of results to return
+ Limit param.Opt[int64] `query:"limit,omitzero" json:"-"`
+ // Number of results to skip
+ Offset param.Opt[int64] `query:"offset,omitzero" json:"-"`
+ // Filter by profile name
+ ProfileName param.Opt[string] `query:"profile_name,omitzero" json:"-"`
+ paramObj
+}
+
+// URLQuery serializes [AuthConnectionListParams]'s query parameters as
+// `url.Values`.
+func (r AuthConnectionListParams) URLQuery() (v url.Values, err error) {
+ return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{
+ ArrayFormat: apiquery.ArrayQueryFormatComma,
+ NestedFormat: apiquery.NestedQueryFormatBrackets,
+ })
+}
+
+type AuthConnectionLoginParams struct {
+ // Request to start a login flow
+ LoginRequest LoginRequestParam
+ paramObj
+}
+
+func (r AuthConnectionLoginParams) MarshalJSON() (data []byte, err error) {
+ return shimjson.Marshal(r.LoginRequest)
+}
+func (r *AuthConnectionLoginParams) UnmarshalJSON(data []byte) error {
+ return json.Unmarshal(data, &r.LoginRequest)
+}
+
+type AuthConnectionSubmitParams struct {
+ // Request to submit field values for login
+ SubmitFieldsRequest SubmitFieldsRequestParam
+ paramObj
+}
+
+func (r AuthConnectionSubmitParams) MarshalJSON() (data []byte, err error) {
+ return shimjson.Marshal(r.SubmitFieldsRequest)
+}
+func (r *AuthConnectionSubmitParams) UnmarshalJSON(data []byte) error {
+ return json.Unmarshal(data, &r.SubmitFieldsRequest)
+}
diff --git a/authconnection_test.go b/authconnection_test.go
new file mode 100644
index 0000000..d619ada
--- /dev/null
+++ b/authconnection_test.go
@@ -0,0 +1,195 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+package kernel_test
+
+import (
+ "context"
+ "errors"
+ "os"
+ "testing"
+
+ "github.com/kernel/kernel-go-sdk"
+ "github.com/kernel/kernel-go-sdk/internal/testutil"
+ "github.com/kernel/kernel-go-sdk/option"
+)
+
+func TestAuthConnectionNewWithOptionalParams(t *testing.T) {
+ t.Skip("Prism tests are disabled")
+ baseURL := "http://localhost:4010"
+ if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
+ baseURL = envURL
+ }
+ if !testutil.CheckTestServer(t, baseURL) {
+ return
+ }
+ client := kernel.NewClient(
+ option.WithBaseURL(baseURL),
+ option.WithAPIKey("My API Key"),
+ )
+ _, err := client.Auth.Connections.New(context.TODO(), kernel.AuthConnectionNewParams{
+ ManagedAuthCreateRequest: kernel.ManagedAuthCreateRequestParam{
+ Domain: "netflix.com",
+ ProfileName: "user-123",
+ AllowedDomains: []string{"login.netflix.com", "auth.netflix.com"},
+ Credential: kernel.ManagedAuthCreateRequestCredentialParam{
+ Auto: kernel.Bool(true),
+ Name: kernel.String("my-netflix-creds"),
+ Path: kernel.String("Personal/Netflix"),
+ Provider: kernel.String("my-1p"),
+ },
+ HealthCheckInterval: kernel.Int(3600),
+ LoginURL: kernel.String("https://netflix.com/login"),
+ Proxy: kernel.ManagedAuthCreateRequestProxyParam{
+ ProxyID: kernel.String("proxy_id"),
+ },
+ },
+ })
+ if err != nil {
+ var apierr *kernel.Error
+ if errors.As(err, &apierr) {
+ t.Log(string(apierr.DumpRequest(true)))
+ }
+ t.Fatalf("err should be nil: %s", err.Error())
+ }
+}
+
+func TestAuthConnectionGet(t *testing.T) {
+ t.Skip("Prism tests are disabled")
+ baseURL := "http://localhost:4010"
+ if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
+ baseURL = envURL
+ }
+ if !testutil.CheckTestServer(t, baseURL) {
+ return
+ }
+ client := kernel.NewClient(
+ option.WithBaseURL(baseURL),
+ option.WithAPIKey("My API Key"),
+ )
+ _, err := client.Auth.Connections.Get(context.TODO(), "id")
+ if err != nil {
+ var apierr *kernel.Error
+ if errors.As(err, &apierr) {
+ t.Log(string(apierr.DumpRequest(true)))
+ }
+ t.Fatalf("err should be nil: %s", err.Error())
+ }
+}
+
+func TestAuthConnectionListWithOptionalParams(t *testing.T) {
+ t.Skip("Prism tests are disabled")
+ baseURL := "http://localhost:4010"
+ if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
+ baseURL = envURL
+ }
+ if !testutil.CheckTestServer(t, baseURL) {
+ return
+ }
+ client := kernel.NewClient(
+ option.WithBaseURL(baseURL),
+ option.WithAPIKey("My API Key"),
+ )
+ _, err := client.Auth.Connections.List(context.TODO(), kernel.AuthConnectionListParams{
+ Domain: kernel.String("domain"),
+ Limit: kernel.Int(100),
+ Offset: kernel.Int(0),
+ ProfileName: kernel.String("profile_name"),
+ })
+ if err != nil {
+ var apierr *kernel.Error
+ if errors.As(err, &apierr) {
+ t.Log(string(apierr.DumpRequest(true)))
+ }
+ t.Fatalf("err should be nil: %s", err.Error())
+ }
+}
+
+func TestAuthConnectionDelete(t *testing.T) {
+ t.Skip("Prism tests are disabled")
+ baseURL := "http://localhost:4010"
+ if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
+ baseURL = envURL
+ }
+ if !testutil.CheckTestServer(t, baseURL) {
+ return
+ }
+ client := kernel.NewClient(
+ option.WithBaseURL(baseURL),
+ option.WithAPIKey("My API Key"),
+ )
+ err := client.Auth.Connections.Delete(context.TODO(), "id")
+ if err != nil {
+ var apierr *kernel.Error
+ if errors.As(err, &apierr) {
+ t.Log(string(apierr.DumpRequest(true)))
+ }
+ t.Fatalf("err should be nil: %s", err.Error())
+ }
+}
+
+func TestAuthConnectionLoginWithOptionalParams(t *testing.T) {
+ t.Skip("Prism tests are disabled")
+ baseURL := "http://localhost:4010"
+ if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
+ baseURL = envURL
+ }
+ if !testutil.CheckTestServer(t, baseURL) {
+ return
+ }
+ client := kernel.NewClient(
+ option.WithBaseURL(baseURL),
+ option.WithAPIKey("My API Key"),
+ )
+ _, err := client.Auth.Connections.Login(
+ context.TODO(),
+ "id",
+ kernel.AuthConnectionLoginParams{
+ LoginRequest: kernel.LoginRequestParam{
+ SaveCredentialAs: kernel.String("my-netflix-login"),
+ },
+ },
+ )
+ if err != nil {
+ var apierr *kernel.Error
+ if errors.As(err, &apierr) {
+ t.Log(string(apierr.DumpRequest(true)))
+ }
+ t.Fatalf("err should be nil: %s", err.Error())
+ }
+}
+
+func TestAuthConnectionSubmitWithOptionalParams(t *testing.T) {
+ t.Skip("Prism tests are disabled")
+ baseURL := "http://localhost:4010"
+ if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
+ baseURL = envURL
+ }
+ if !testutil.CheckTestServer(t, baseURL) {
+ return
+ }
+ client := kernel.NewClient(
+ option.WithBaseURL(baseURL),
+ option.WithAPIKey("My API Key"),
+ )
+ _, err := client.Auth.Connections.Submit(
+ context.TODO(),
+ "id",
+ kernel.AuthConnectionSubmitParams{
+ SubmitFieldsRequest: kernel.SubmitFieldsRequestParam{
+ Fields: map[string]string{
+ "email": "user@example.com",
+ "password": "secret",
+ },
+ MfaOptionID: kernel.String("sms"),
+ SSOButtonSelector: kernel.String("xpath=//button[contains(text(), 'Continue with Google')]"),
+ },
+ },
+ )
+ if err != nil {
+ var apierr *kernel.Error
+ if errors.As(err, &apierr) {
+ t.Log(string(apierr.DumpRequest(true)))
+ }
+ t.Fatalf("err should be nil: %s", err.Error())
+ }
+}
diff --git a/client.go b/client.go
index a1ac662..4106fd4 100644
--- a/client.go
+++ b/client.go
@@ -22,6 +22,7 @@ type Client struct {
Invocations InvocationService
Browsers BrowserService
Profiles ProfileService
+ Auth AuthService
Proxies ProxyService
Extensions ExtensionService
BrowserPools BrowserPoolService
@@ -57,6 +58,7 @@ func NewClient(opts ...option.RequestOption) (r Client) {
r.Invocations = NewInvocationService(opts...)
r.Browsers = NewBrowserService(opts...)
r.Profiles = NewProfileService(opts...)
+ r.Auth = NewAuthService(opts...)
r.Proxies = NewProxyService(opts...)
r.Extensions = NewExtensionService(opts...)
r.BrowserPools = NewBrowserPoolService(opts...)
diff --git a/credentialprovider.go b/credentialprovider.go
index ded8c4f..2e6c172 100644
--- a/credentialprovider.go
+++ b/credentialprovider.go
@@ -42,7 +42,7 @@ func NewCredentialProviderService(opts ...option.RequestOption) (r CredentialPro
// credential lookup.
func (r *CredentialProviderService) New(ctx context.Context, body CredentialProviderNewParams, opts ...option.RequestOption) (res *CredentialProvider, err error) {
opts = slices.Concat(r.Options, opts)
- path := "org/credential-providers"
+ path := "org/credential_providers"
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...)
return
}
@@ -54,7 +54,7 @@ func (r *CredentialProviderService) Get(ctx context.Context, id string, opts ...
err = errors.New("missing required id parameter")
return
}
- path := fmt.Sprintf("org/credential-providers/%s", id)
+ path := fmt.Sprintf("org/credential_providers/%s", id)
err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...)
return
}
@@ -66,7 +66,7 @@ func (r *CredentialProviderService) Update(ctx context.Context, id string, body
err = errors.New("missing required id parameter")
return
}
- path := fmt.Sprintf("org/credential-providers/%s", id)
+ path := fmt.Sprintf("org/credential_providers/%s", id)
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPatch, path, body, &res, opts...)
return
}
@@ -74,7 +74,7 @@ func (r *CredentialProviderService) Update(ctx context.Context, id string, body
// List external credential providers configured for the organization.
func (r *CredentialProviderService) List(ctx context.Context, opts ...option.RequestOption) (res *[]CredentialProvider, err error) {
opts = slices.Concat(r.Options, opts)
- path := "org/credential-providers"
+ path := "org/credential_providers"
err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...)
return
}
@@ -87,11 +87,24 @@ func (r *CredentialProviderService) Delete(ctx context.Context, id string, opts
err = errors.New("missing required id parameter")
return
}
- path := fmt.Sprintf("org/credential-providers/%s", id)
+ path := fmt.Sprintf("org/credential_providers/%s", id)
err = requestconfig.ExecuteNewRequest(ctx, http.MethodDelete, path, nil, nil, opts...)
return
}
+// Returns available credential items (e.g., 1Password login items) from the
+// provider.
+func (r *CredentialProviderService) ListItems(ctx context.Context, id string, opts ...option.RequestOption) (res *CredentialProviderListItemsResponse, err error) {
+ opts = slices.Concat(r.Options, opts)
+ if id == "" {
+ err = errors.New("missing required id parameter")
+ return
+ }
+ path := fmt.Sprintf("org/credential_providers/%s/items", id)
+ err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...)
+ return
+}
+
// Validate the credential provider's token and list accessible vaults.
func (r *CredentialProviderService) Test(ctx context.Context, id string, opts ...option.RequestOption) (res *CredentialProviderTestResult, err error) {
opts = slices.Concat(r.Options, opts)
@@ -99,17 +112,19 @@ func (r *CredentialProviderService) Test(ctx context.Context, id string, opts ..
err = errors.New("missing required id parameter")
return
}
- path := fmt.Sprintf("org/credential-providers/%s/test", id)
+ path := fmt.Sprintf("org/credential_providers/%s/test", id)
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, nil, &res, opts...)
return
}
// Request to create an external credential provider
//
-// The properties Token, ProviderType are required.
+// The properties Token, Name, ProviderType are required.
type CreateCredentialProviderRequestParam struct {
// Service account token for the provider (e.g., 1Password service account token)
Token string `json:"token,required"`
+ // Human-readable name for this provider instance (unique per org)
+ Name string `json:"name,required"`
// Type of credential provider
//
// Any of "onepassword".
@@ -143,6 +158,8 @@ type CredentialProvider struct {
CreatedAt time.Time `json:"created_at,required" format:"date-time"`
// Whether the provider is enabled for credential lookups
Enabled bool `json:"enabled,required"`
+ // Human-readable name for this provider instance
+ Name string `json:"name,required"`
// Priority order for credential lookups (lower numbers are checked first)
Priority int64 `json:"priority,required"`
// Type of credential provider
@@ -156,6 +173,7 @@ type CredentialProvider struct {
ID respjson.Field
CreatedAt respjson.Field
Enabled respjson.Field
+ Name respjson.Field
Priority respjson.Field
ProviderType respjson.Field
UpdatedAt respjson.Field
@@ -177,6 +195,39 @@ const (
CredentialProviderProviderTypeOnepassword CredentialProviderProviderType = "onepassword"
)
+// A credential item from an external provider (e.g., a 1Password login item)
+type CredentialProviderItem struct {
+ // Unique identifier for the item within the provider
+ ID string `json:"id,required"`
+ // Path to reference this item (VaultName/ItemTitle format)
+ Path string `json:"path,required"`
+ // Display name of the credential item
+ Title string `json:"title,required"`
+ // ID of the vault containing this item
+ VaultID string `json:"vault_id,required"`
+ // Name of the vault containing this item
+ VaultName string `json:"vault_name,required"`
+ // URLs associated with this credential
+ URLs []string `json:"urls"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ ID respjson.Field
+ Path respjson.Field
+ Title respjson.Field
+ VaultID respjson.Field
+ VaultName respjson.Field
+ URLs respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r CredentialProviderItem) RawJSON() string { return r.JSON.raw }
+func (r *CredentialProviderItem) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
// Result of testing a credential provider connection
type CredentialProviderTestResult struct {
// Whether the connection test was successful
@@ -229,6 +280,8 @@ type UpdateCredentialProviderRequestParam struct {
CacheTtlSeconds param.Opt[int64] `json:"cache_ttl_seconds,omitzero"`
// Whether the provider is enabled for credential lookups
Enabled param.Opt[bool] `json:"enabled,omitzero"`
+ // Human-readable name for this provider instance
+ Name param.Opt[string] `json:"name,omitzero"`
// Priority order for credential lookups (lower numbers are checked first)
Priority param.Opt[int64] `json:"priority,omitzero"`
paramObj
@@ -242,6 +295,22 @@ func (r *UpdateCredentialProviderRequestParam) UnmarshalJSON(data []byte) error
return apijson.UnmarshalRoot(data, r)
}
+type CredentialProviderListItemsResponse struct {
+ Items []CredentialProviderItem `json:"items"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ Items respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r CredentialProviderListItemsResponse) RawJSON() string { return r.JSON.raw }
+func (r *CredentialProviderListItemsResponse) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
type CredentialProviderNewParams struct {
// Request to create an external credential provider
CreateCredentialProviderRequest CreateCredentialProviderRequestParam
diff --git a/credentialprovider_test.go b/credentialprovider_test.go
index 18e4a02..296378c 100644
--- a/credentialprovider_test.go
+++ b/credentialprovider_test.go
@@ -29,6 +29,7 @@ func TestCredentialProviderNewWithOptionalParams(t *testing.T) {
_, err := client.CredentialProviders.New(context.TODO(), kernel.CredentialProviderNewParams{
CreateCredentialProviderRequest: kernel.CreateCredentialProviderRequestParam{
Token: "ops_eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
+ Name: "my-1password",
ProviderType: kernel.CreateCredentialProviderRequestProviderTypeOnepassword,
CacheTtlSeconds: kernel.Int(300),
},
@@ -86,6 +87,7 @@ func TestCredentialProviderUpdateWithOptionalParams(t *testing.T) {
Token: kernel.String("ops_eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."),
CacheTtlSeconds: kernel.Int(300),
Enabled: kernel.Bool(true),
+ Name: kernel.String("my-1password"),
Priority: kernel.Int(0),
},
},
@@ -145,6 +147,29 @@ func TestCredentialProviderDelete(t *testing.T) {
}
}
+func TestCredentialProviderListItems(t *testing.T) {
+ t.Skip("Prism tests are disabled")
+ baseURL := "http://localhost:4010"
+ if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
+ baseURL = envURL
+ }
+ if !testutil.CheckTestServer(t, baseURL) {
+ return
+ }
+ client := kernel.NewClient(
+ option.WithBaseURL(baseURL),
+ option.WithAPIKey("My API Key"),
+ )
+ _, err := client.CredentialProviders.ListItems(context.TODO(), "id")
+ if err != nil {
+ var apierr *kernel.Error
+ if errors.As(err, &apierr) {
+ t.Log(string(apierr.DumpRequest(true)))
+ }
+ t.Fatalf("err should be nil: %s", err.Error())
+ }
+}
+
func TestCredentialProviderTest(t *testing.T) {
t.Skip("Prism tests are disabled")
baseURL := "http://localhost:4010"
diff --git a/internal/version.go b/internal/version.go
index d26ea0a..becd05d 100644
--- a/internal/version.go
+++ b/internal/version.go
@@ -2,4 +2,4 @@
package internal
-const PackageVersion = "0.31.0" // x-release-please-version
+const PackageVersion = "0.31.1" // x-release-please-version
diff --git a/shared/constant/constants.go b/shared/constant/constants.go
index 38af58e..104ffd3 100644
--- a/shared/constant/constants.go
+++ b/shared/constant/constants.go
@@ -24,6 +24,7 @@ type DeploymentState string // Always "deployment_state"
type Error string // Always "error"
type InvocationState string // Always "invocation_state"
type Log string // Always "log"
+type ManagedAuthState string // Always "managed_auth_state"
type SseHeartbeat string // Always "sse_heartbeat"
func (c AppVersionSummary) Default() AppVersionSummary { return "app_version_summary" }
@@ -32,6 +33,7 @@ func (c DeploymentState) Default() DeploymentState { return "deployment_stat
func (c Error) Default() Error { return "error" }
func (c InvocationState) Default() InvocationState { return "invocation_state" }
func (c Log) Default() Log { return "log" }
+func (c ManagedAuthState) Default() ManagedAuthState { return "managed_auth_state" }
func (c SseHeartbeat) Default() SseHeartbeat { return "sse_heartbeat" }
func (c AppVersionSummary) MarshalJSON() ([]byte, error) { return marshalString(c) }
@@ -40,6 +42,7 @@ func (c DeploymentState) MarshalJSON() ([]byte, error) { return marshalString(
func (c Error) MarshalJSON() ([]byte, error) { return marshalString(c) }
func (c InvocationState) MarshalJSON() ([]byte, error) { return marshalString(c) }
func (c Log) MarshalJSON() ([]byte, error) { return marshalString(c) }
+func (c ManagedAuthState) MarshalJSON() ([]byte, error) { return marshalString(c) }
func (c SseHeartbeat) MarshalJSON() ([]byte, error) { return marshalString(c) }
type constant[T any] interface {
diff --git a/shared/shared.go b/shared/shared.go
index fe7b089..d5248c3 100644
--- a/shared/shared.go
+++ b/shared/shared.go
@@ -260,7 +260,8 @@ func (r *ErrorEvent) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-func (ErrorEvent) ImplInvocationFollowResponseUnion() {}
+func (ErrorEvent) ImplInvocationFollowResponseUnion() {}
+func (ErrorEvent) ImplAuthConnectionFollowResponseUnion() {}
type ErrorModel struct {
// Application-specific error code (machine-readable)
@@ -308,7 +309,8 @@ func (r *HeartbeatEvent) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-func (HeartbeatEvent) ImplInvocationFollowResponseUnion() {}
+func (HeartbeatEvent) ImplInvocationFollowResponseUnion() {}
+func (HeartbeatEvent) ImplAuthConnectionFollowResponseUnion() {}
// A log entry from the application.
type LogEvent struct {