From a291bbe344e9a197085335fbf53a689996032506 Mon Sep 17 00:00:00 2001
From: sjmiller609 <7516283+sjmiller609@users.noreply.github.com>
Date: Fri, 7 Aug 2026 18:40:13 +0000
Subject: [PATCH 1/4] Build SDK
Stainless-Generated-From: c3154a77aed79d47586b251ff42bd0ae8afccb77
---
.stats.yml | 2 +-
api.md | 21 ++
auditlog.go | 3 +
auditlogexportdestination.go | 391 ++++++++++++++++++++++++++++++
auditlogexportdestination_test.go | 178 ++++++++++++++
5 files changed, 594 insertions(+), 1 deletion(-)
create mode 100644 auditlogexportdestination.go
create mode 100644 auditlogexportdestination_test.go
diff --git a/.stats.yml b/.stats.yml
index 71c320f..4bb27f8 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1 +1 @@
-configured_endpoints: 127
+configured_endpoints: 133
diff --git a/api.md b/api.md
index bbd5b3c..3842c2e 100644
--- a/api.md
+++ b/api.md
@@ -438,6 +438,27 @@ Methods:
- client.AuditLogs.List(ctx context.Context, query kernel.AuditLogListParams) (\*pagination.PageTokenPagination[kernel.AuditLogEntry], error)
- client.AuditLogs.ExportChunk(ctx context.Context, query kernel.AuditLogExportChunkParams) (\*http.Response, error)
+## ExportDestinations
+
+Params Types:
+
+- kernel.CreateAuditLogExportDestinationRequestParam
+- kernel.UpdateAuditLogExportDestinationRequestParam
+
+Response Types:
+
+- kernel.AuditLogExportDestination
+- kernel.AuditLogExportDestinationTestResult
+
+Methods:
+
+- client.AuditLogs.ExportDestinations.New(ctx context.Context, body kernel.AuditLogExportDestinationNewParams) (\*kernel.AuditLogExportDestination, error)
+- client.AuditLogs.ExportDestinations.Get(ctx context.Context, id string) (\*kernel.AuditLogExportDestination, error)
+- client.AuditLogs.ExportDestinations.Update(ctx context.Context, id string, body kernel.AuditLogExportDestinationUpdateParams) (\*kernel.AuditLogExportDestination, error)
+- client.AuditLogs.ExportDestinations.List(ctx context.Context, query kernel.AuditLogExportDestinationListParams) (\*pagination.OffsetPagination[kernel.AuditLogExportDestination], error)
+- client.AuditLogs.ExportDestinations.Delete(ctx context.Context, id string) error
+- client.AuditLogs.ExportDestinations.Test(ctx context.Context, id string) (\*kernel.AuditLogExportDestinationTestResult, error)
+
# APIKeys
Response Types:
diff --git a/auditlog.go b/auditlog.go
index 9096e7c..665df86 100644
--- a/auditlog.go
+++ b/auditlog.go
@@ -28,6 +28,8 @@ import (
// the [NewAuditLogService] method instead.
type AuditLogService struct {
Options []option.RequestOption
+ // Read audit log records for the authenticated organization.
+ ExportDestinations AuditLogExportDestinationService
}
// NewAuditLogService generates a new service that applies the given options to
@@ -36,6 +38,7 @@ type AuditLogService struct {
func NewAuditLogService(opts ...option.RequestOption) (r AuditLogService) {
r = AuditLogService{}
r.Options = opts
+ r.ExportDestinations = NewAuditLogExportDestinationService(opts...)
return
}
diff --git a/auditlogexportdestination.go b/auditlogexportdestination.go
new file mode 100644
index 0000000..db967d3
--- /dev/null
+++ b/auditlogexportdestination.go
@@ -0,0 +1,391 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+package kernel
+
+import (
+ "context"
+ "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"
+)
+
+// Read audit log records for the authenticated organization.
+//
+// AuditLogExportDestinationService 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 [NewAuditLogExportDestinationService] method instead.
+type AuditLogExportDestinationService struct {
+ Options []option.RequestOption
+}
+
+// NewAuditLogExportDestinationService 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 NewAuditLogExportDestinationService(opts ...option.RequestOption) (r AuditLogExportDestinationService) {
+ r = AuditLogExportDestinationService{}
+ r.Options = opts
+ return
+}
+
+// Create a paused destination. Activate it with a status update once the
+// destination test passes. Requires an active Enterprise plan.
+func (r *AuditLogExportDestinationService) New(ctx context.Context, body AuditLogExportDestinationNewParams, opts ...option.RequestOption) (res *AuditLogExportDestination, err error) {
+ opts = slices.Concat(r.Options, opts)
+ path := "audit-logs/export/destinations"
+ err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...)
+ return res, err
+}
+
+// Retrieve details for a single audit log export destination by its ID.
+func (r *AuditLogExportDestinationService) Get(ctx context.Context, id string, opts ...option.RequestOption) (res *AuditLogExportDestination, err error) {
+ opts = slices.Concat(r.Options, opts)
+ if id == "" {
+ err = errors.New("missing required id parameter")
+ return nil, err
+ }
+ path := fmt.Sprintf("audit-logs/export/destinations/%s", id)
+ err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...)
+ return res, err
+}
+
+// Apply a partial update to a destination. Requires an active Enterprise plan.
+// Returns 409 when the destination was changed concurrently, because the merged
+// configuration this request validated is no longer the one that would be stored;
+// retry against fresh state. Pausing prevents new delivery attempts, but an S3
+// upload already in progress may complete after the response.
+func (r *AuditLogExportDestinationService) Update(ctx context.Context, id string, body AuditLogExportDestinationUpdateParams, opts ...option.RequestOption) (res *AuditLogExportDestination, err error) {
+ opts = slices.Concat(r.Options, opts)
+ if id == "" {
+ err = errors.New("missing required id parameter")
+ return nil, err
+ }
+ path := fmt.Sprintf("audit-logs/export/destinations/%s", id)
+ err = requestconfig.ExecuteNewRequest(ctx, http.MethodPatch, path, body, &res, opts...)
+ return res, err
+}
+
+// List audit log export destinations for the organization with pagination support.
+func (r *AuditLogExportDestinationService) List(ctx context.Context, query AuditLogExportDestinationListParams, opts ...option.RequestOption) (res *pagination.OffsetPagination[AuditLogExportDestination], err error) {
+ var raw *http.Response
+ opts = slices.Concat(r.Options, opts)
+ opts = append([]option.RequestOption{option.WithResponseInto(&raw)}, opts...)
+ path := "audit-logs/export/destinations"
+ 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 audit log export destinations for the organization with pagination support.
+func (r *AuditLogExportDestinationService) ListAutoPaging(ctx context.Context, query AuditLogExportDestinationListParams, opts ...option.RequestOption) *pagination.OffsetPaginationAutoPager[AuditLogExportDestination] {
+ return pagination.NewOffsetPaginationAutoPager(r.List(ctx, query, opts...))
+}
+
+// Soft delete the destination and prevent new delivery attempts. An S3 upload
+// already in progress may complete after the response.
+func (r *AuditLogExportDestinationService) 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 err
+ }
+ path := fmt.Sprintf("audit-logs/export/destinations/%s", id)
+ err = requestconfig.ExecuteNewRequest(ctx, http.MethodDelete, path, nil, nil, opts...)
+ return err
+}
+
+// Verify the destination is writable by assuming the configured role and uploading
+// a temporary probe object with the same request metadata as a real delivery.
+// Requires an active Enterprise plan.
+func (r *AuditLogExportDestinationService) Test(ctx context.Context, id string, opts ...option.RequestOption) (res *AuditLogExportDestinationTestResult, err error) {
+ opts = slices.Concat(r.Options, opts)
+ if id == "" {
+ err = errors.New("missing required id parameter")
+ return nil, err
+ }
+ path := fmt.Sprintf("audit-logs/export/destinations/%s/test", id)
+ err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, nil, &res, opts...)
+ return res, err
+}
+
+// An organization-scoped audit log export destination.
+//
+// Delivery is at-least-once for rows visible when their window is committed: a
+// delivery that is retried rewrites the same object, and the same `event_id` can
+// appear in more than one object, so consumers must deduplicate on `event_id`.
+// Each event-time window is held for ten minutes before it commits; a row that
+// becomes visible after its window is committed may not be delivered.
+//
+// Objects are written as
+// `/destination_id=/org_id=/date=/hour=/-.jsonl.gz`,
+// where `date` and `hour` are the UTC calendar hour that fully contains every row
+// in the object, so the layout is safe to register as a Hive-partitioned table.
+// The object name is derived from the rows it holds, so a retried delivery
+// rewrites its own object.
+type AuditLogExportDestination struct {
+ ID string `json:"id" api:"required"`
+ Bucket string `json:"bucket" api:"required"`
+ ConsecutiveFailures int64 `json:"consecutive_failures" api:"required"`
+ CreatedAt time.Time `json:"created_at" api:"required" format:"date-time"`
+ ExternalID string `json:"external_id" api:"required"`
+ // Any of "jsonl.gz".
+ Format AuditLogExportDestinationFormat `json:"format" api:"required"`
+ // The Kernel role that assumes `role_arn` in your account to deliver logs. Allow
+ // this role as the principal in your role's trust policy, and require
+ // `external_id` as the `sts:ExternalId` condition.
+ //
+ // Recreating a destination issues a new `external_id`, which the trust policy has
+ // to be updated to match.
+ KernelRoleArn string `json:"kernel_role_arn" api:"required"`
+ Prefix string `json:"prefix" api:"required"`
+ Region string `json:"region" api:"required"`
+ RoleArn string `json:"role_arn" api:"required"`
+ // Pausing prevents new delivery attempts. An S3 upload already in progress may
+ // complete after the pause response; its rows can appear again after the
+ // destination is resumed.
+ //
+ // Any of "active", "paused".
+ Status AuditLogExportDestinationStatus `json:"status" api:"required"`
+ // Any of "s3".
+ Type AuditLogExportDestinationType `json:"type" api:"required"`
+ UpdatedAt time.Time `json:"updated_at" api:"required" format:"date-time"`
+ KmsKeyID string `json:"kms_key_id"`
+ // Sanitized description of the most recent delivery failure.
+ LastError string `json:"last_error"`
+ LastErrorAt time.Time `json:"last_error_at" format:"date-time"`
+ // Opaque, versioned checkpoint for forward-only continuous export. This value is
+ // not compatible with audit-log list page tokens.
+ //
+ // Delivery starts at the moment the destination is activated, so events recorded
+ // before that are not delivered. Pausing stops delivery and resuming starts again
+ // from the time of the resume: events recorded while a destination was paused are
+ // never exported, and pausing is not a way to defer delivery.
+ LastExportedCursor string `json:"last_exported_cursor"`
+ LastSuccessAt time.Time `json:"last_success_at" format:"date-time"`
+ NextAttemptAt time.Time `json:"next_attempt_at" format:"date-time"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ ID respjson.Field
+ Bucket respjson.Field
+ ConsecutiveFailures respjson.Field
+ CreatedAt respjson.Field
+ ExternalID respjson.Field
+ Format respjson.Field
+ KernelRoleArn respjson.Field
+ Prefix respjson.Field
+ Region respjson.Field
+ RoleArn respjson.Field
+ Status respjson.Field
+ Type respjson.Field
+ UpdatedAt respjson.Field
+ KmsKeyID respjson.Field
+ LastError respjson.Field
+ LastErrorAt respjson.Field
+ LastExportedCursor respjson.Field
+ LastSuccessAt respjson.Field
+ NextAttemptAt respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r AuditLogExportDestination) RawJSON() string { return r.JSON.raw }
+func (r *AuditLogExportDestination) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+type AuditLogExportDestinationFormat string
+
+const (
+ AuditLogExportDestinationFormatJSONLGz AuditLogExportDestinationFormat = "jsonl.gz"
+)
+
+// Pausing prevents new delivery attempts. An S3 upload already in progress may
+// complete after the pause response; its rows can appear again after the
+// destination is resumed.
+type AuditLogExportDestinationStatus string
+
+const (
+ AuditLogExportDestinationStatusActive AuditLogExportDestinationStatus = "active"
+ AuditLogExportDestinationStatusPaused AuditLogExportDestinationStatus = "paused"
+)
+
+type AuditLogExportDestinationType string
+
+const (
+ AuditLogExportDestinationTypeS3 AuditLogExportDestinationType = "s3"
+)
+
+type AuditLogExportDestinationTestResult struct {
+ // Any of "assume_role", "put_object", "complete".
+ Stage AuditLogExportDestinationTestResultStage `json:"stage" api:"required"`
+ Success bool `json:"success" api:"required"`
+ Error AuditLogExportDestinationTestResultError `json:"error"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ Stage respjson.Field
+ Success respjson.Field
+ Error respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r AuditLogExportDestinationTestResult) RawJSON() string { return r.JSON.raw }
+func (r *AuditLogExportDestinationTestResult) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+type AuditLogExportDestinationTestResultStage string
+
+const (
+ AuditLogExportDestinationTestResultStageAssumeRole AuditLogExportDestinationTestResultStage = "assume_role"
+ AuditLogExportDestinationTestResultStagePutObject AuditLogExportDestinationTestResultStage = "put_object"
+ AuditLogExportDestinationTestResultStageComplete AuditLogExportDestinationTestResultStage = "complete"
+)
+
+type AuditLogExportDestinationTestResultError struct {
+ // Any of "assume_role_failed", "put_object_failed".
+ Code string `json:"code" api:"required"`
+ Message string `json:"message" api:"required"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ Code respjson.Field
+ Message respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r AuditLogExportDestinationTestResultError) RawJSON() string { return r.JSON.raw }
+func (r *AuditLogExportDestinationTestResultError) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+// The properties Bucket, Format, Prefix, Region, RoleArn, Type are required.
+type CreateAuditLogExportDestinationRequestParam struct {
+ Bucket string `json:"bucket" api:"required"`
+ // Any of "jsonl.gz".
+ Format CreateAuditLogExportDestinationRequestFormat `json:"format,omitzero" api:"required"`
+ Prefix string `json:"prefix" api:"required"`
+ Region string `json:"region" api:"required"`
+ RoleArn string `json:"role_arn" api:"required"`
+ // Any of "s3".
+ Type CreateAuditLogExportDestinationRequestType `json:"type,omitzero" api:"required"`
+ KmsKeyID param.Opt[string] `json:"kms_key_id,omitzero"`
+ paramObj
+}
+
+func (r CreateAuditLogExportDestinationRequestParam) MarshalJSON() (data []byte, err error) {
+ type shadow CreateAuditLogExportDestinationRequestParam
+ return param.MarshalObject(r, (*shadow)(&r))
+}
+func (r *CreateAuditLogExportDestinationRequestParam) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+type CreateAuditLogExportDestinationRequestFormat string
+
+const (
+ CreateAuditLogExportDestinationRequestFormatJSONLGz CreateAuditLogExportDestinationRequestFormat = "jsonl.gz"
+)
+
+type CreateAuditLogExportDestinationRequestType string
+
+const (
+ CreateAuditLogExportDestinationRequestTypeS3 CreateAuditLogExportDestinationRequestType = "s3"
+)
+
+type UpdateAuditLogExportDestinationRequestParam struct {
+ Bucket param.Opt[string] `json:"bucket,omitzero"`
+ // KMS key ID, alias, or ARN. Set to an empty string to remove the configured KMS
+ // key; omit or send null to leave unchanged.
+ KmsKeyID param.Opt[string] `json:"kms_key_id,omitzero"`
+ Prefix param.Opt[string] `json:"prefix,omitzero"`
+ Region param.Opt[string] `json:"region,omitzero"`
+ RoleArn param.Opt[string] `json:"role_arn,omitzero"`
+ // Any of "active", "paused".
+ Status UpdateAuditLogExportDestinationRequestStatus `json:"status,omitzero"`
+ paramObj
+}
+
+func (r UpdateAuditLogExportDestinationRequestParam) MarshalJSON() (data []byte, err error) {
+ type shadow UpdateAuditLogExportDestinationRequestParam
+ return param.MarshalObject(r, (*shadow)(&r))
+}
+func (r *UpdateAuditLogExportDestinationRequestParam) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+type UpdateAuditLogExportDestinationRequestStatus string
+
+const (
+ UpdateAuditLogExportDestinationRequestStatusActive UpdateAuditLogExportDestinationRequestStatus = "active"
+ UpdateAuditLogExportDestinationRequestStatusPaused UpdateAuditLogExportDestinationRequestStatus = "paused"
+)
+
+type AuditLogExportDestinationNewParams struct {
+ CreateAuditLogExportDestinationRequest CreateAuditLogExportDestinationRequestParam
+ paramObj
+}
+
+func (r AuditLogExportDestinationNewParams) MarshalJSON() (data []byte, err error) {
+ return shimjson.Marshal(r.CreateAuditLogExportDestinationRequest)
+}
+func (r *AuditLogExportDestinationNewParams) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+type AuditLogExportDestinationUpdateParams struct {
+ UpdateAuditLogExportDestinationRequest UpdateAuditLogExportDestinationRequestParam
+ paramObj
+}
+
+func (r AuditLogExportDestinationUpdateParams) MarshalJSON() (data []byte, err error) {
+ return shimjson.Marshal(r.UpdateAuditLogExportDestinationRequest)
+}
+func (r *AuditLogExportDestinationUpdateParams) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+type AuditLogExportDestinationListParams struct {
+ // Limit the number of destinations to return.
+ Limit param.Opt[int64] `query:"limit,omitzero" json:"-"`
+ // Offset the number of destinations to return.
+ Offset param.Opt[int64] `query:"offset,omitzero" json:"-"`
+ paramObj
+}
+
+// URLQuery serializes [AuditLogExportDestinationListParams]'s query parameters as
+// `url.Values`.
+func (r AuditLogExportDestinationListParams) URLQuery() (v url.Values, err error) {
+ return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{
+ ArrayFormat: apiquery.ArrayQueryFormatComma,
+ NestedFormat: apiquery.NestedQueryFormatBrackets,
+ })
+}
diff --git a/auditlogexportdestination_test.go b/auditlogexportdestination_test.go
new file mode 100644
index 0000000..b9ceb30
--- /dev/null
+++ b/auditlogexportdestination_test.go
@@ -0,0 +1,178 @@
+// 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 TestAuditLogExportDestinationNewWithOptionalParams(t *testing.T) {
+ t.Skip("Mock server 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.AuditLogs.ExportDestinations.New(context.TODO(), kernel.AuditLogExportDestinationNewParams{
+ CreateAuditLogExportDestinationRequest: kernel.CreateAuditLogExportDestinationRequestParam{
+ Bucket: "xxx",
+ Format: kernel.CreateAuditLogExportDestinationRequestFormatJSONLGz,
+ Prefix: "prefix",
+ Region: "x",
+ RoleArn: "x",
+ Type: kernel.CreateAuditLogExportDestinationRequestTypeS3,
+ KmsKeyID: kernel.String("kms_key_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 TestAuditLogExportDestinationGet(t *testing.T) {
+ t.Skip("Mock server 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.AuditLogs.ExportDestinations.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 TestAuditLogExportDestinationUpdateWithOptionalParams(t *testing.T) {
+ t.Skip("Mock server 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.AuditLogs.ExportDestinations.Update(
+ context.TODO(),
+ "id",
+ kernel.AuditLogExportDestinationUpdateParams{
+ UpdateAuditLogExportDestinationRequest: kernel.UpdateAuditLogExportDestinationRequestParam{
+ Bucket: kernel.String("xxx"),
+ KmsKeyID: kernel.String("kms_key_id"),
+ Prefix: kernel.String("prefix"),
+ Region: kernel.String("x"),
+ RoleArn: kernel.String("x"),
+ Status: kernel.UpdateAuditLogExportDestinationRequestStatusActive,
+ },
+ },
+ )
+ 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 TestAuditLogExportDestinationListWithOptionalParams(t *testing.T) {
+ t.Skip("Mock server 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.AuditLogs.ExportDestinations.List(context.TODO(), kernel.AuditLogExportDestinationListParams{
+ Limit: kernel.Int(1),
+ Offset: kernel.Int(0),
+ })
+ 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 TestAuditLogExportDestinationDelete(t *testing.T) {
+ t.Skip("Mock server 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.AuditLogs.ExportDestinations.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 TestAuditLogExportDestinationTest(t *testing.T) {
+ t.Skip("Mock server 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.AuditLogs.ExportDestinations.Test(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())
+ }
+}
From 4e924dfdce39fb1110e8f935c2061c24da60cf6f Mon Sep 17 00:00:00 2001
From: "kernel-internal[bot]"
<260533166+kernel-internal[bot]@users.noreply.github.com>
Date: Sat, 8 Aug 2026 19:56:25 +0000
Subject: [PATCH 2/4] feat: Forward egress deploy owner attribution
Stainless-Generated-From: bf54567a8acdc52aeb3c888518c493f38306bc23
---
api.md | 7 +
authconnection.go | 369 +++++++++++++++++++++++++++++++++++------
authconnection_test.go | 147 ++++++++++++++++
browser.go | 186 ++++++++++++++++++++-
browser_test.go | 10 ++
browserpool.go | 8 +-
invocation.go | 8 +-
7 files changed, 675 insertions(+), 60 deletions(-)
diff --git a/api.md b/api.md
index 9b2b461..7bb412f 100644
--- a/api.md
+++ b/api.md
@@ -69,11 +69,16 @@ Methods:
Params Types:
+- kernel.BrowserProxyConfigParam
+- kernel.BrowserProxyMode
- kernel.Tags
Response Types:
- kernel.BrowserPoolRef
+- kernel.BrowserProxy
+- kernel.BrowserProxyConfig
+- kernel.BrowserProxyMode
- kernel.BrowserUsage
- kernel.Profile
- kernel.Tags
@@ -287,6 +292,7 @@ Methods:
Params Types:
+- kernel.ManagedAuthBrowserConfigParam
- kernel.ManagedAuthCreateRequestParam
- kernel.ManagedAuthUpdateRequestParam
- kernel.SubmitFieldsRequestParam
@@ -295,6 +301,7 @@ Response Types:
- kernel.LoginResponse
- kernel.ManagedAuth
+- kernel.ManagedAuthBrowserConfig
- kernel.ManagedAuthTimelineEvent
- kernel.SubmitFieldsResponse
- kernel.AuthConnectionFollowResponseUnion
diff --git a/authconnection.go b/authconnection.go
index f3c6d5b..fcf5202 100644
--- a/authconnection.go
+++ b/authconnection.go
@@ -288,13 +288,17 @@ type ManagedAuth struct {
// when `health_checks` is false. When false, expired sessions detected by a health
// check are marked as `NEEDS_AUTH` instead of attempting re-auth.
AutoReauth bool `json:"auto_reauth"`
+ // Default browser configuration for login, reauthentication, and health-check
+ // sessions.
+ Browser ManagedAuthBrowserConfig `json:"browser"`
// ID of the underlying browser session driving the current flow (present when flow
// in progress). Use this to inspect or terminate the browser session via the
// `/browsers` API.
BrowserSessionID string `json:"browser_session_id" api:"nullable"`
- // Browser telemetry configuration used by this connection's browser sessions by
- // default. The exact create-browser configuration is preserved and can be
- // overridden per-login.
+ // Deprecated. Use browser.telemetry. Retained during migration for existing
+ // clients.
+ //
+ // Deprecated: deprecated
BrowserTelemetry ManagedAuthBrowserTelemetry `json:"browser_telemetry" api:"nullable"`
// Whether Kernel can automatically re-authenticate this connection when the
// session expires. Requires a prior successful login plus either a Kernel
@@ -415,7 +419,10 @@ type ManagedAuth struct {
PendingSSOButtons []ManagedAuthPendingSSOButton `json:"pending_sso_buttons" api:"nullable"`
// URL where the browser landed after successful login
PostLoginURL string `json:"post_login_url" format:"uri"`
- // ID of the proxy associated with this connection, if any.
+ // Deprecated. Read browser.proxy instead. Retained during migration for existing
+ // clients.
+ //
+ // Deprecated: deprecated
ProxyID string `json:"proxy_id"`
// Non-MFA choices presented during the auth flow, such as account selection or org
// pickers (present when flow_step=awaiting_input; may also be present with
@@ -436,6 +443,7 @@ type ManagedAuth struct {
Status respjson.Field
AllowedDomains respjson.Field
AutoReauth respjson.Field
+ Browser respjson.Field
BrowserSessionID respjson.Field
BrowserTelemetry respjson.Field
CanReauth respjson.Field
@@ -484,9 +492,10 @@ const (
ManagedAuthStatusNeedsAuth ManagedAuthStatus = "NEEDS_AUTH"
)
-// Browser telemetry configuration used by this connection's browser sessions by
-// default. The exact create-browser configuration is preserved and can be
-// overridden per-login.
+// Deprecated. Use browser.telemetry. Retained during migration for existing
+// clients.
+//
+// Deprecated: deprecated
type ManagedAuthBrowserTelemetry struct {
// Per-category capture flags. The operational categories (control, connection,
// system, captcha) are captured whenever telemetry is enabled; set one to
@@ -897,6 +906,263 @@ func (r *ManagedAuthSignInOption) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
+// Browser configuration applied to browser sessions created for a managed auth
+// connection. Managed auth controls the profile, headless mode, timeout, start
+// URL, kiosk mode, and viewport.
+type ManagedAuthBrowserConfig struct {
+ // Proxy configuration for managed auth browser sessions. Omit on create to derive
+ // the default from stealth, or on update and login to preserve or inherit the
+ // connection default.
+ Proxy BrowserProxyConfig `json:"proxy"`
+ // Whether managed auth browser sessions use stealth mode. Defaults to true when
+ // omitted.
+ Stealth bool `json:"stealth"`
+ // Browser telemetry configuration using the same semantics as browser create.
+ Telemetry ManagedAuthBrowserConfigTelemetry `json:"telemetry" api:"nullable"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ Proxy respjson.Field
+ Stealth respjson.Field
+ Telemetry respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r ManagedAuthBrowserConfig) RawJSON() string { return r.JSON.raw }
+func (r *ManagedAuthBrowserConfig) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+// ToParam converts this ManagedAuthBrowserConfig to a
+// ManagedAuthBrowserConfigParam.
+//
+// Warning: the fields of the param type will not be present. ToParam should only
+// be used at the last possible moment before sending a request. Test for this with
+// ManagedAuthBrowserConfigParam.Overrides()
+func (r ManagedAuthBrowserConfig) ToParam() ManagedAuthBrowserConfigParam {
+ return param.Override[ManagedAuthBrowserConfigParam](json.RawMessage(r.RawJSON()))
+}
+
+// Browser telemetry configuration using the same semantics as browser create.
+type ManagedAuthBrowserConfigTelemetry struct {
+ // Per-category capture flags. The operational categories (control, connection,
+ // system, captcha) are captured whenever telemetry is enabled; set one to
+ // enabled=false to opt out. The CDP categories (console, network, page,
+ // interaction) and screenshot are off by default; set enabled=true to opt in. On
+ // create, provided categories layer onto the default set. On update, provided
+ // categories merge onto the session's current config; when no telemetry is active
+ // this falls back to the default set (matching create). If browser is omitted or
+ // empty, the default set is used. A browser config that disables every category
+ // stops capture on update and starts no capture on create.
+ Browser BrowserTelemetryCategoriesConfig `json:"browser"`
+ // Request shortcut for browser telemetry capture. True enables capture; with no
+ // browser category settings it captures the default set (control, connection,
+ // system, captcha), and any browser category settings are layered onto that
+ // default set. On update, enabled=true resolves the config fresh from the default
+ // set plus any provided categories, replacing the session's current selection
+ // rather than merging onto it; omit enabled to merge categories onto the current
+ // selection instead. False stops capture on update and starts no capture on
+ // create. enabled=false cannot be combined with browser category settings.
+ Enabled bool `json:"enabled"`
+ // Where to export this session's captured telemetry. Omit to capture without
+ // exporting.
+ Export ManagedAuthBrowserConfigTelemetryExport `json:"export"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ Browser respjson.Field
+ Enabled respjson.Field
+ Export respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r ManagedAuthBrowserConfigTelemetry) RawJSON() string { return r.JSON.raw }
+func (r *ManagedAuthBrowserConfigTelemetry) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+// Where to export this session's captured telemetry. Omit to capture without
+// exporting.
+type ManagedAuthBrowserConfigTelemetryExport struct {
+ // Export captured telemetry over OTLP to one of the org's configured destinations.
+ Otlp ManagedAuthBrowserConfigTelemetryExportOtlp `json:"otlp"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ Otlp respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r ManagedAuthBrowserConfigTelemetryExport) RawJSON() string { return r.JSON.raw }
+func (r *ManagedAuthBrowserConfigTelemetryExport) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+// Export captured telemetry over OTLP to one of the org's configured destinations.
+type ManagedAuthBrowserConfigTelemetryExportOtlp struct {
+ // OTLP destination to export this session's captured telemetry to. Provide either
+ // id or name. Requires telemetry capture to be enabled.
+ Destination ManagedAuthBrowserConfigTelemetryExportOtlpDestination `json:"destination"`
+ // Whether to export captured telemetry over OTLP. Setting destination implies
+ // enabled=true, so this only needs to be set explicitly to disable export
+ // (enabled=false with a destination is rejected).
+ Enabled bool `json:"enabled"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ Destination respjson.Field
+ Enabled respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r ManagedAuthBrowserConfigTelemetryExportOtlp) RawJSON() string { return r.JSON.raw }
+func (r *ManagedAuthBrowserConfigTelemetryExportOtlp) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+// OTLP destination to export this session's captured telemetry to. Provide either
+// id or name. Requires telemetry capture to be enabled.
+type ManagedAuthBrowserConfigTelemetryExportOtlpDestination struct {
+ // OTLP destination ID
+ ID string `json:"id"`
+ // OTLP destination name
+ Name string `json:"name"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ ID respjson.Field
+ Name respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r ManagedAuthBrowserConfigTelemetryExportOtlpDestination) RawJSON() string { return r.JSON.raw }
+func (r *ManagedAuthBrowserConfigTelemetryExportOtlpDestination) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+// Browser configuration applied to browser sessions created for a managed auth
+// connection. Managed auth controls the profile, headless mode, timeout, start
+// URL, kiosk mode, and viewport.
+type ManagedAuthBrowserConfigParam struct {
+ // Whether managed auth browser sessions use stealth mode. Defaults to true when
+ // omitted.
+ Stealth param.Opt[bool] `json:"stealth,omitzero"`
+ // Browser telemetry configuration using the same semantics as browser create.
+ Telemetry ManagedAuthBrowserConfigTelemetryParam `json:"telemetry,omitzero"`
+ // Proxy configuration for managed auth browser sessions. Omit on create to derive
+ // the default from stealth, or on update and login to preserve or inherit the
+ // connection default.
+ Proxy BrowserProxyConfigParam `json:"proxy,omitzero"`
+ paramObj
+}
+
+func (r ManagedAuthBrowserConfigParam) MarshalJSON() (data []byte, err error) {
+ type shadow ManagedAuthBrowserConfigParam
+ return param.MarshalObject(r, (*shadow)(&r))
+}
+func (r *ManagedAuthBrowserConfigParam) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+// Browser telemetry configuration using the same semantics as browser create.
+type ManagedAuthBrowserConfigTelemetryParam struct {
+ // Request shortcut for browser telemetry capture. True enables capture; with no
+ // browser category settings it captures the default set (control, connection,
+ // system, captcha), and any browser category settings are layered onto that
+ // default set. On update, enabled=true resolves the config fresh from the default
+ // set plus any provided categories, replacing the session's current selection
+ // rather than merging onto it; omit enabled to merge categories onto the current
+ // selection instead. False stops capture on update and starts no capture on
+ // create. enabled=false cannot be combined with browser category settings.
+ Enabled param.Opt[bool] `json:"enabled,omitzero"`
+ // Per-category capture flags. The operational categories (control, connection,
+ // system, captcha) are captured whenever telemetry is enabled; set one to
+ // enabled=false to opt out. The CDP categories (console, network, page,
+ // interaction) and screenshot are off by default; set enabled=true to opt in. On
+ // create, provided categories layer onto the default set. On update, provided
+ // categories merge onto the session's current config; when no telemetry is active
+ // this falls back to the default set (matching create). If browser is omitted or
+ // empty, the default set is used. A browser config that disables every category
+ // stops capture on update and starts no capture on create.
+ Browser BrowserTelemetryCategoriesConfigParam `json:"browser,omitzero"`
+ // Where to export this session's captured telemetry. Omit to capture without
+ // exporting.
+ Export ManagedAuthBrowserConfigTelemetryExportParam `json:"export,omitzero"`
+ paramObj
+}
+
+func (r ManagedAuthBrowserConfigTelemetryParam) MarshalJSON() (data []byte, err error) {
+ type shadow ManagedAuthBrowserConfigTelemetryParam
+ return param.MarshalObject(r, (*shadow)(&r))
+}
+func (r *ManagedAuthBrowserConfigTelemetryParam) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+// Where to export this session's captured telemetry. Omit to capture without
+// exporting.
+type ManagedAuthBrowserConfigTelemetryExportParam struct {
+ // Export captured telemetry over OTLP to one of the org's configured destinations.
+ Otlp ManagedAuthBrowserConfigTelemetryExportOtlpParam `json:"otlp,omitzero"`
+ paramObj
+}
+
+func (r ManagedAuthBrowserConfigTelemetryExportParam) MarshalJSON() (data []byte, err error) {
+ type shadow ManagedAuthBrowserConfigTelemetryExportParam
+ return param.MarshalObject(r, (*shadow)(&r))
+}
+func (r *ManagedAuthBrowserConfigTelemetryExportParam) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+// Export captured telemetry over OTLP to one of the org's configured destinations.
+type ManagedAuthBrowserConfigTelemetryExportOtlpParam struct {
+ // Whether to export captured telemetry over OTLP. Setting destination implies
+ // enabled=true, so this only needs to be set explicitly to disable export
+ // (enabled=false with a destination is rejected).
+ Enabled param.Opt[bool] `json:"enabled,omitzero"`
+ // OTLP destination to export this session's captured telemetry to. Provide either
+ // id or name. Requires telemetry capture to be enabled.
+ Destination ManagedAuthBrowserConfigTelemetryExportOtlpDestinationParam `json:"destination,omitzero"`
+ paramObj
+}
+
+func (r ManagedAuthBrowserConfigTelemetryExportOtlpParam) MarshalJSON() (data []byte, err error) {
+ type shadow ManagedAuthBrowserConfigTelemetryExportOtlpParam
+ return param.MarshalObject(r, (*shadow)(&r))
+}
+func (r *ManagedAuthBrowserConfigTelemetryExportOtlpParam) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+// OTLP destination to export this session's captured telemetry to. Provide either
+// id or name. Requires telemetry capture to be enabled.
+type ManagedAuthBrowserConfigTelemetryExportOtlpDestinationParam struct {
+ // OTLP destination ID
+ ID param.Opt[string] `json:"id,omitzero"`
+ // OTLP destination name
+ Name param.Opt[string] `json:"name,omitzero"`
+ paramObj
+}
+
+func (r ManagedAuthBrowserConfigTelemetryExportOtlpDestinationParam) MarshalJSON() (data []byte, err error) {
+ type shadow ManagedAuthBrowserConfigTelemetryExportOtlpDestinationParam
+ return param.MarshalObject(r, (*shadow)(&r))
+}
+func (r *ManagedAuthBrowserConfigTelemetryExportOtlpDestinationParam) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
// Request to create an auth connection for a profile and domain
//
// The properties Domain, ProfileName are required.
@@ -934,9 +1200,10 @@ type ManagedAuthCreateRequestParam struct {
// Whether to save credentials after every successful login. Defaults to true.
// One-time codes (TOTP, SMS, etc.) are not saved.
SaveCredentials param.Opt[bool] `json:"save_credentials,omitzero"`
- // Browser telemetry configuration used by this connection's browser sessions by
- // default. Uses the exact create-browser configuration. Can be overridden
- // per-login.
+ // Deprecated. Use browser.telemetry. Retained during migration for existing
+ // clients.
+ //
+ // Deprecated: deprecated
BrowserTelemetry ManagedAuthCreateRequestBrowserTelemetryParam `json:"browser_telemetry,omitzero"`
// Additional domains valid for this auth flow (besides the primary domain). Useful
// when login pages redirect to different domains.
@@ -956,16 +1223,18 @@ type ManagedAuthCreateRequestParam struct {
// - OneLogin: \*.onelogin.com
// - Ping Identity: _.pingone.com, _.pingidentity.com
AllowedDomains []string `json:"allowed_domains,omitzero"`
+ // Default browser configuration for login, reauthentication, and health-check
+ // sessions.
+ Browser ManagedAuthBrowserConfigParam `json:"browser,omitzero"`
// Reference to credentials for the auth connection. 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"`
- // Proxy selection. Provide either id or name. The proxy must be in the same
- // project as the resource referencing it. When selecting by name, the name must
- // match exactly one active proxy in the project. Ambiguous names return a 400; use
- // id for stable references.
+ // Deprecated. Use browser.proxy. Retained during migration for existing clients.
+ //
+ // Deprecated: deprecated
Proxy ManagedAuthCreateRequestProxyParam `json:"proxy,omitzero"`
paramObj
}
@@ -978,9 +1247,10 @@ func (r *ManagedAuthCreateRequestParam) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-// Browser telemetry configuration used by this connection's browser sessions by
-// default. Uses the exact create-browser configuration. Can be overridden
-// per-login.
+// Deprecated. Use browser.telemetry. Retained during migration for existing
+// clients.
+//
+// Deprecated: deprecated
type ManagedAuthCreateRequestBrowserTelemetryParam struct {
// Request shortcut for browser telemetry capture. True enables capture; with no
// browser category settings it captures the default set (control, connection,
@@ -1094,10 +1364,9 @@ func (r *ManagedAuthCreateRequestCredentialParam) UnmarshalJSON(data []byte) err
return apijson.UnmarshalRoot(data, r)
}
-// Proxy selection. Provide either id or name. The proxy must be in the same
-// project as the resource referencing it. When selecting by name, the name must
-// match exactly one active proxy in the project. Ambiguous names return a 400; use
-// id for stable references.
+// Deprecated. Use browser.proxy. Retained during migration for existing clients.
+//
+// Deprecated: deprecated
type ManagedAuthCreateRequestProxyParam struct {
// Proxy ID
ID param.Opt[string] `json:"id,omitzero"`
@@ -1257,22 +1526,25 @@ type ManagedAuthUpdateRequestParam struct {
RecordSession param.Opt[bool] `json:"record_session,omitzero"`
// Whether to save credentials after every successful login
SaveCredentials param.Opt[bool] `json:"save_credentials,omitzero"`
- // Browser telemetry configuration used by future browser sessions for this
- // connection. Uses the exact create-browser configuration. Set enabled to false to
- // disable telemetry.
+ // Deprecated. Use browser.telemetry. Retained during migration for existing
+ // clients.
+ //
+ // Deprecated: deprecated
BrowserTelemetry ManagedAuthUpdateRequestBrowserTelemetryParam `json:"browser_telemetry,omitzero"`
// Additional domains valid for this auth flow (replaces existing list)
AllowedDomains []string `json:"allowed_domains,omitzero"`
+ // Browser configuration updates for future login, reauthentication, and
+ // health-check sessions. Omitted properties remain unchanged.
+ Browser ManagedAuthBrowserConfigParam `json:"browser,omitzero"`
// Reference to credentials for the auth connection. Use one of:
//
// - { name } for Kernel credentials
// - { provider, path } for external provider item
// - { provider, auto: true } for external provider domain lookup
Credential ManagedAuthUpdateRequestCredentialParam `json:"credential,omitzero"`
- // Proxy selection. Provide either id or name. The proxy must be in the same
- // project as the resource referencing it. When selecting by name, the name must
- // match exactly one active proxy in the project. Ambiguous names return a 400; use
- // id for stable references.
+ // Deprecated. Use browser.proxy. Retained during migration for existing clients.
+ //
+ // Deprecated: deprecated
Proxy ManagedAuthUpdateRequestProxyParam `json:"proxy,omitzero"`
paramObj
}
@@ -1285,9 +1557,10 @@ func (r *ManagedAuthUpdateRequestParam) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-// Browser telemetry configuration used by future browser sessions for this
-// connection. Uses the exact create-browser configuration. Set enabled to false to
-// disable telemetry.
+// Deprecated. Use browser.telemetry. Retained during migration for existing
+// clients.
+//
+// Deprecated: deprecated
type ManagedAuthUpdateRequestBrowserTelemetryParam struct {
// Request shortcut for browser telemetry capture. True enables capture; with no
// browser category settings it captures the default set (control, connection,
@@ -1401,10 +1674,9 @@ func (r *ManagedAuthUpdateRequestCredentialParam) UnmarshalJSON(data []byte) err
return apijson.UnmarshalRoot(data, r)
}
-// Proxy selection. Provide either id or name. The proxy must be in the same
-// project as the resource referencing it. When selecting by name, the name must
-// match exactly one active proxy in the project. Ambiguous names return a 400; use
-// id for stable references.
+// Deprecated. Use browser.proxy. Retained during migration for existing clients.
+//
+// Deprecated: deprecated
type ManagedAuthUpdateRequestProxyParam struct {
// Proxy ID
ID param.Opt[string] `json:"id,omitzero"`
@@ -1933,14 +2205,13 @@ type AuthConnectionLoginParams struct {
// Override the connection's default for recording this login's browser session.
// When omitted, the connection's record_session default is used.
RecordSession param.Opt[bool] `json:"record_session,omitzero"`
- // Override the connection's default browser telemetry configuration for this
- // login. When omitted, the connection's browser_telemetry default is used. Uses
- // the exact create-browser configuration.
+ // Deprecated. Use browser.telemetry. Retained during migration for existing
+ // clients.
BrowserTelemetry AuthConnectionLoginParamsBrowserTelemetry `json:"browser_telemetry,omitzero"`
- // Proxy selection. Provide either id or name. The proxy must be in the same
- // project as the resource referencing it. When selecting by name, the name must
- // match exactly one active proxy in the project. Ambiguous names return a 400; use
- // id for stable references.
+ // Browser configuration override for this login. Omitted properties inherit the
+ // connection defaults.
+ Browser ManagedAuthBrowserConfigParam `json:"browser,omitzero"`
+ // Deprecated. Use browser.proxy. Retained during migration for existing clients.
Proxy AuthConnectionLoginParamsProxy `json:"proxy,omitzero"`
paramObj
}
@@ -1953,9 +2224,10 @@ func (r *AuthConnectionLoginParams) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-// Override the connection's default browser telemetry configuration for this
-// login. When omitted, the connection's browser_telemetry default is used. Uses
-// the exact create-browser configuration.
+// Deprecated. Use browser.telemetry. Retained during migration for existing
+// clients.
+//
+// Deprecated: deprecated
type AuthConnectionLoginParamsBrowserTelemetry struct {
// Request shortcut for browser telemetry capture. True enables capture; with no
// browser category settings it captures the default set (control, connection,
@@ -2044,10 +2316,9 @@ func (r *AuthConnectionLoginParamsBrowserTelemetryExportOtlpDestination) Unmarsh
return apijson.UnmarshalRoot(data, r)
}
-// Proxy selection. Provide either id or name. The proxy must be in the same
-// project as the resource referencing it. When selecting by name, the name must
-// match exactly one active proxy in the project. Ambiguous names return a 400; use
-// id for stable references.
+// Deprecated. Use browser.proxy. Retained during migration for existing clients.
+//
+// Deprecated: deprecated
type AuthConnectionLoginParamsProxy struct {
// Proxy ID
ID param.Opt[string] `json:"id,omitzero"`
diff --git a/authconnection_test.go b/authconnection_test.go
index b8b1c8b..aefb2ba 100644
--- a/authconnection_test.go
+++ b/authconnection_test.go
@@ -32,6 +32,55 @@ func TestAuthConnectionNewWithOptionalParams(t *testing.T) {
ProfileName: "user-123",
AllowedDomains: []string{"login.netflix.com", "auth.netflix.com"},
AutoReauth: kernel.Bool(true),
+ Browser: kernel.ManagedAuthBrowserConfigParam{
+ Proxy: kernel.BrowserProxyConfigParam{
+ ID: kernel.String("x"),
+ Mode: kernel.BrowserProxyModeDirect,
+ Name: kernel.String("x"),
+ },
+ Stealth: kernel.Bool(false),
+ Telemetry: kernel.ManagedAuthBrowserConfigTelemetryParam{
+ Browser: kernel.BrowserTelemetryCategoriesConfigParam{
+ Captcha: kernel.BrowserTelemetryCategoryConfigParam{
+ Enabled: kernel.Bool(true),
+ },
+ Connection: kernel.BrowserTelemetryCategoryConfigParam{
+ Enabled: kernel.Bool(true),
+ },
+ Console: kernel.BrowserTelemetryCategoryConfigParam{
+ Enabled: kernel.Bool(true),
+ },
+ Control: kernel.BrowserTelemetryCategoryConfigParam{
+ Enabled: kernel.Bool(true),
+ },
+ Interaction: kernel.BrowserTelemetryCategoryConfigParam{
+ Enabled: kernel.Bool(true),
+ },
+ Network: kernel.BrowserTelemetryCategoryConfigParam{
+ Enabled: kernel.Bool(true),
+ },
+ Page: kernel.BrowserTelemetryCategoryConfigParam{
+ Enabled: kernel.Bool(true),
+ },
+ Screenshot: kernel.BrowserTelemetryCategoryConfigParam{
+ Enabled: kernel.Bool(true),
+ },
+ System: kernel.BrowserTelemetryCategoryConfigParam{
+ Enabled: kernel.Bool(true),
+ },
+ },
+ Enabled: kernel.Bool(true),
+ Export: kernel.ManagedAuthBrowserConfigTelemetryExportParam{
+ Otlp: kernel.ManagedAuthBrowserConfigTelemetryExportOtlpParam{
+ Destination: kernel.ManagedAuthBrowserConfigTelemetryExportOtlpDestinationParam{
+ ID: kernel.String("id"),
+ Name: kernel.String("name"),
+ },
+ Enabled: kernel.Bool(true),
+ },
+ },
+ },
+ },
BrowserTelemetry: kernel.ManagedAuthCreateRequestBrowserTelemetryParam{
Browser: kernel.BrowserTelemetryCategoriesConfigParam{
Captcha: kernel.BrowserTelemetryCategoryConfigParam{
@@ -142,6 +191,55 @@ func TestAuthConnectionUpdateWithOptionalParams(t *testing.T) {
ManagedAuthUpdateRequest: kernel.ManagedAuthUpdateRequestParam{
AllowedDomains: []string{"login.netflix.com", "auth.netflix.com"},
AutoReauth: kernel.Bool(true),
+ Browser: kernel.ManagedAuthBrowserConfigParam{
+ Proxy: kernel.BrowserProxyConfigParam{
+ ID: kernel.String("x"),
+ Mode: kernel.BrowserProxyModeDirect,
+ Name: kernel.String("x"),
+ },
+ Stealth: kernel.Bool(false),
+ Telemetry: kernel.ManagedAuthBrowserConfigTelemetryParam{
+ Browser: kernel.BrowserTelemetryCategoriesConfigParam{
+ Captcha: kernel.BrowserTelemetryCategoryConfigParam{
+ Enabled: kernel.Bool(true),
+ },
+ Connection: kernel.BrowserTelemetryCategoryConfigParam{
+ Enabled: kernel.Bool(true),
+ },
+ Console: kernel.BrowserTelemetryCategoryConfigParam{
+ Enabled: kernel.Bool(true),
+ },
+ Control: kernel.BrowserTelemetryCategoryConfigParam{
+ Enabled: kernel.Bool(true),
+ },
+ Interaction: kernel.BrowserTelemetryCategoryConfigParam{
+ Enabled: kernel.Bool(true),
+ },
+ Network: kernel.BrowserTelemetryCategoryConfigParam{
+ Enabled: kernel.Bool(true),
+ },
+ Page: kernel.BrowserTelemetryCategoryConfigParam{
+ Enabled: kernel.Bool(true),
+ },
+ Screenshot: kernel.BrowserTelemetryCategoryConfigParam{
+ Enabled: kernel.Bool(true),
+ },
+ System: kernel.BrowserTelemetryCategoryConfigParam{
+ Enabled: kernel.Bool(true),
+ },
+ },
+ Enabled: kernel.Bool(true),
+ Export: kernel.ManagedAuthBrowserConfigTelemetryExportParam{
+ Otlp: kernel.ManagedAuthBrowserConfigTelemetryExportOtlpParam{
+ Destination: kernel.ManagedAuthBrowserConfigTelemetryExportOtlpDestinationParam{
+ ID: kernel.String("id"),
+ Name: kernel.String("name"),
+ },
+ Enabled: kernel.Bool(true),
+ },
+ },
+ },
+ },
BrowserTelemetry: kernel.ManagedAuthUpdateRequestBrowserTelemetryParam{
Browser: kernel.BrowserTelemetryCategoriesConfigParam{
Captcha: kernel.BrowserTelemetryCategoryConfigParam{
@@ -279,6 +377,55 @@ func TestAuthConnectionLoginWithOptionalParams(t *testing.T) {
context.TODO(),
"id",
kernel.AuthConnectionLoginParams{
+ Browser: kernel.ManagedAuthBrowserConfigParam{
+ Proxy: kernel.BrowserProxyConfigParam{
+ ID: kernel.String("x"),
+ Mode: kernel.BrowserProxyModeDirect,
+ Name: kernel.String("x"),
+ },
+ Stealth: kernel.Bool(false),
+ Telemetry: kernel.ManagedAuthBrowserConfigTelemetryParam{
+ Browser: kernel.BrowserTelemetryCategoriesConfigParam{
+ Captcha: kernel.BrowserTelemetryCategoryConfigParam{
+ Enabled: kernel.Bool(true),
+ },
+ Connection: kernel.BrowserTelemetryCategoryConfigParam{
+ Enabled: kernel.Bool(true),
+ },
+ Console: kernel.BrowserTelemetryCategoryConfigParam{
+ Enabled: kernel.Bool(true),
+ },
+ Control: kernel.BrowserTelemetryCategoryConfigParam{
+ Enabled: kernel.Bool(true),
+ },
+ Interaction: kernel.BrowserTelemetryCategoryConfigParam{
+ Enabled: kernel.Bool(true),
+ },
+ Network: kernel.BrowserTelemetryCategoryConfigParam{
+ Enabled: kernel.Bool(true),
+ },
+ Page: kernel.BrowserTelemetryCategoryConfigParam{
+ Enabled: kernel.Bool(true),
+ },
+ Screenshot: kernel.BrowserTelemetryCategoryConfigParam{
+ Enabled: kernel.Bool(true),
+ },
+ System: kernel.BrowserTelemetryCategoryConfigParam{
+ Enabled: kernel.Bool(true),
+ },
+ },
+ Enabled: kernel.Bool(true),
+ Export: kernel.ManagedAuthBrowserConfigTelemetryExportParam{
+ Otlp: kernel.ManagedAuthBrowserConfigTelemetryExportOtlpParam{
+ Destination: kernel.ManagedAuthBrowserConfigTelemetryExportOtlpDestinationParam{
+ ID: kernel.String("id"),
+ Name: kernel.String("name"),
+ },
+ Enabled: kernel.Bool(true),
+ },
+ },
+ },
+ },
BrowserTelemetry: kernel.AuthConnectionLoginParamsBrowserTelemetry{
Browser: kernel.BrowserTelemetryCategoriesConfigParam{
Captcha: kernel.BrowserTelemetryCategoryConfigParam{
diff --git a/browser.go b/browser.go
index 1fb4801..bcdca34 100644
--- a/browser.go
+++ b/browser.go
@@ -5,6 +5,7 @@ package kernel
import (
"bytes"
"context"
+ "encoding/json"
"errors"
"fmt"
"io"
@@ -186,6 +187,131 @@ func (r *BrowserPoolRef) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
+// Resolved proxy configuration for a browser session. Selected proxies are
+// returned by stable ID.
+type BrowserProxy struct {
+ // Selected proxy ID.
+ ID string `json:"id"`
+ // Proxy egress mode. direct forces no proxy regardless of stealth. default uses
+ // the browser's stealth-derived default: Kernel's default stealth proxy when
+ // stealth=true, or direct egress when stealth=false. default is primarily useful
+ // on browser update to restore the browser default after selected-proxy egress.
+ //
+ // Any of "direct", "default".
+ Mode BrowserProxyMode `json:"mode"`
+ // Selected proxy name.
+ Name string `json:"name"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ ID respjson.Field
+ Mode respjson.Field
+ Name respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r BrowserProxy) RawJSON() string { return r.JSON.raw }
+func (r *BrowserProxy) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+// Browser proxy configuration. Provide exactly one of mode, id, or name; an empty
+// object is invalid. Set mode to direct for no proxy regardless of stealth. Set
+// mode to default to use the browser's stealth-derived default: Kernel's default
+// stealth proxy when stealth=true, or direct egress when stealth=false. Select id
+// or name to use that proxy regardless of stealth. The selected proxy must be in
+// the same project as the browser. Names must match exactly one active proxy; use
+// id for stable references. Proxy configuration changes only egress and does not
+// change stealth or CAPTCHA solver behavior. A stealth browser using mode=direct
+// still runs in stealth mode with the CAPTCHA solver enabled. When proxy is
+// omitted on browser creation, stealth browsers use Kernel's default stealth proxy
+// and non-stealth browsers use direct egress. When omitted on update, the current
+// configuration is unchanged.
+type BrowserProxyConfig struct {
+ // Proxy ID.
+ ID string `json:"id"`
+ // Proxy egress mode. direct forces no proxy regardless of stealth. default uses
+ // the browser's stealth-derived default: Kernel's default stealth proxy when
+ // stealth=true, or direct egress when stealth=false. default is primarily useful
+ // on browser update to restore the browser default after selected-proxy egress.
+ //
+ // Any of "direct", "default".
+ Mode BrowserProxyMode `json:"mode"`
+ // Proxy name. Must match exactly one active proxy in the project.
+ Name string `json:"name"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ ID respjson.Field
+ Mode respjson.Field
+ Name respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r BrowserProxyConfig) RawJSON() string { return r.JSON.raw }
+func (r *BrowserProxyConfig) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+// ToParam converts this BrowserProxyConfig to a BrowserProxyConfigParam.
+//
+// Warning: the fields of the param type will not be present. ToParam should only
+// be used at the last possible moment before sending a request. Test for this with
+// BrowserProxyConfigParam.Overrides()
+func (r BrowserProxyConfig) ToParam() BrowserProxyConfigParam {
+ return param.Override[BrowserProxyConfigParam](json.RawMessage(r.RawJSON()))
+}
+
+// Browser proxy configuration. Provide exactly one of mode, id, or name; an empty
+// object is invalid. Set mode to direct for no proxy regardless of stealth. Set
+// mode to default to use the browser's stealth-derived default: Kernel's default
+// stealth proxy when stealth=true, or direct egress when stealth=false. Select id
+// or name to use that proxy regardless of stealth. The selected proxy must be in
+// the same project as the browser. Names must match exactly one active proxy; use
+// id for stable references. Proxy configuration changes only egress and does not
+// change stealth or CAPTCHA solver behavior. A stealth browser using mode=direct
+// still runs in stealth mode with the CAPTCHA solver enabled. When proxy is
+// omitted on browser creation, stealth browsers use Kernel's default stealth proxy
+// and non-stealth browsers use direct egress. When omitted on update, the current
+// configuration is unchanged.
+type BrowserProxyConfigParam struct {
+ // Proxy ID.
+ ID param.Opt[string] `json:"id,omitzero"`
+ // Proxy name. Must match exactly one active proxy in the project.
+ Name param.Opt[string] `json:"name,omitzero"`
+ // Proxy egress mode. direct forces no proxy regardless of stealth. default uses
+ // the browser's stealth-derived default: Kernel's default stealth proxy when
+ // stealth=true, or direct egress when stealth=false. default is primarily useful
+ // on browser update to restore the browser default after selected-proxy egress.
+ //
+ // Any of "direct", "default".
+ Mode BrowserProxyMode `json:"mode,omitzero"`
+ paramObj
+}
+
+func (r BrowserProxyConfigParam) MarshalJSON() (data []byte, err error) {
+ type shadow BrowserProxyConfigParam
+ return param.MarshalObject(r, (*shadow)(&r))
+}
+func (r *BrowserProxyConfigParam) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+// Proxy egress mode. direct forces no proxy regardless of stealth. default uses
+// the browser's stealth-derived default: Kernel's default stealth proxy when
+// stealth=true, or direct egress when stealth=false. default is primarily useful
+// on browser update to restore the browser default after selected-proxy egress.
+type BrowserProxyMode string
+
+const (
+ BrowserProxyModeDirect BrowserProxyMode = "direct"
+ BrowserProxyModeDefault BrowserProxyMode = "default"
+)
+
// Session usage metrics.
type BrowserUsage struct {
// Time in milliseconds the session was actively running.
@@ -276,7 +402,12 @@ type BrowserNewResponse struct {
// Whether changes made during this browser session are saved back to its profile
// when the session ends. Omitted when no profile is attached.
ProfileSaveChanges bool `json:"profile_save_changes"`
- // ID of the proxy associated with this browser session, if any.
+ // Resolved proxy configuration for this browser session.
+ Proxy BrowserProxy `json:"proxy"`
+ // ID of the proxy associated with this browser session, if any. Deprecated in
+ // favor of proxy.
+ //
+ // Deprecated: deprecated
ProxyID string `json:"proxy_id"`
// URL the session was asked to navigate to on creation, if any. Recorded for
// debugging. Navigation is fire-and-forget — the URL is dispatched to the browser
@@ -323,6 +454,7 @@ type BrowserNewResponse struct {
Pool respjson.Field
Profile respjson.Field
ProfileSaveChanges respjson.Field
+ Proxy respjson.Field
ProxyID respjson.Field
StartURL respjson.Field
Tags respjson.Field
@@ -380,7 +512,12 @@ type BrowserGetResponse struct {
// Whether changes made during this browser session are saved back to its profile
// when the session ends. Omitted when no profile is attached.
ProfileSaveChanges bool `json:"profile_save_changes"`
- // ID of the proxy associated with this browser session, if any.
+ // Resolved proxy configuration for this browser session.
+ Proxy BrowserProxy `json:"proxy"`
+ // ID of the proxy associated with this browser session, if any. Deprecated in
+ // favor of proxy.
+ //
+ // Deprecated: deprecated
ProxyID string `json:"proxy_id"`
// URL the session was asked to navigate to on creation, if any. Recorded for
// debugging. Navigation is fire-and-forget — the URL is dispatched to the browser
@@ -427,6 +564,7 @@ type BrowserGetResponse struct {
Pool respjson.Field
Profile respjson.Field
ProfileSaveChanges respjson.Field
+ Proxy respjson.Field
ProxyID respjson.Field
StartURL respjson.Field
Tags respjson.Field
@@ -484,7 +622,12 @@ type BrowserUpdateResponse struct {
// Whether changes made during this browser session are saved back to its profile
// when the session ends. Omitted when no profile is attached.
ProfileSaveChanges bool `json:"profile_save_changes"`
- // ID of the proxy associated with this browser session, if any.
+ // Resolved proxy configuration for this browser session.
+ Proxy BrowserProxy `json:"proxy"`
+ // ID of the proxy associated with this browser session, if any. Deprecated in
+ // favor of proxy.
+ //
+ // Deprecated: deprecated
ProxyID string `json:"proxy_id"`
// URL the session was asked to navigate to on creation, if any. Recorded for
// debugging. Navigation is fire-and-forget — the URL is dispatched to the browser
@@ -531,6 +674,7 @@ type BrowserUpdateResponse struct {
Pool respjson.Field
Profile respjson.Field
ProfileSaveChanges respjson.Field
+ Proxy respjson.Field
ProxyID respjson.Field
StartURL respjson.Field
Tags respjson.Field
@@ -588,7 +732,12 @@ type BrowserListResponse struct {
// Whether changes made during this browser session are saved back to its profile
// when the session ends. Omitted when no profile is attached.
ProfileSaveChanges bool `json:"profile_save_changes"`
- // ID of the proxy associated with this browser session, if any.
+ // Resolved proxy configuration for this browser session.
+ Proxy BrowserProxy `json:"proxy"`
+ // ID of the proxy associated with this browser session, if any. Deprecated in
+ // favor of proxy.
+ //
+ // Deprecated: deprecated
ProxyID string `json:"proxy_id"`
// URL the session was asked to navigate to on creation, if any. Recorded for
// debugging. Navigation is fire-and-forget — the URL is dispatched to the browser
@@ -635,6 +784,7 @@ type BrowserListResponse struct {
Pool respjson.Field
Profile respjson.Field
ProfileSaveChanges respjson.Field
+ Proxy respjson.Field
ProxyID respjson.Field
StartURL respjson.Field
Tags respjson.Field
@@ -696,14 +846,17 @@ type BrowserNewParams struct {
// changed later via PATCH /browsers/{id_or_name}.
Name param.Opt[string] `json:"name,omitzero"`
// Optional proxy to associate to the browser session. Must reference a proxy in
- // the same project as the browser session.
+ // the same project as the browser session. Deprecated in favor of proxy.
ProxyID param.Opt[string] `json:"proxy_id,omitzero"`
// Optional URL to open when the browser session is created. Navigation is
// best-effort, so navigation failures do not prevent the session from being
// created.
StartURL param.Opt[string] `json:"start_url,omitzero"`
- // If true, launches the browser in stealth mode to reduce detection by anti-bot
- // mechanisms.
+ // If true, launches the browser in stealth mode and enables the CAPTCHA solver.
+ // Defaults to false. When proxy is omitted, stealth browsers use Kernel's default
+ // stealth proxy and non-stealth browsers use direct egress. An explicit proxy
+ // configuration changes only egress; it does not enable or disable stealth or the
+ // CAPTCHA solver.
Stealth param.Opt[bool] `json:"stealth,omitzero"`
// The number of seconds of inactivity before the browser session is terminated.
// Activity includes CDP connections and live view connections. Defaults to 60
@@ -728,6 +881,14 @@ type BrowserNewParams struct {
// specified, the matching profile will be loaded into the browser session.
// Profiles must be created beforehand.
Profile shared.BrowserProfileParam `json:"profile,omitzero"`
+ // Proxy configuration for the browser session. Cannot be combined with proxy_id.
+ // Omit to use the browser default: stealth browsers use Kernel's default stealth
+ // proxy, while non-stealth browsers use direct egress. Set mode to direct to force
+ // direct egress regardless of stealth. Set mode to default to explicitly use the
+ // browser default: Kernel's default stealth proxy when stealth=true, or direct
+ // egress when stealth=false. Select id or name to use that proxy regardless of
+ // stealth. Proxy selection does not change stealth or CAPTCHA solver behavior.
+ Proxy BrowserProxyConfigParam `json:"proxy,omitzero"`
// Optional user-defined key-value tags for the browser session, used to find and
// group sessions later. Can be changed later via PATCH /browsers/{id_or_name}. Up
// to 50 pairs.
@@ -869,10 +1030,10 @@ type BrowserUpdateParams struct {
// within the project.
Name param.Opt[string] `json:"name,omitzero"`
// ID of the proxy to use. Omit to leave unchanged, set to empty string to remove
- // proxy.
+ // proxy. Deprecated in favor of proxy.
ProxyID param.Opt[string] `json:"proxy_id,omitzero"`
// If true, stealth browsers connect directly instead of using the default stealth
- // proxy.
+ // proxy. Deprecated in favor of proxy.mode.
DisableDefaultProxy param.Opt[bool] `json:"disable_default_proxy,omitzero"`
// Telemetry configuration. Omit, set to null, or set to an empty object ({}) to
// leave the existing configuration unchanged. Set enabled to true to enable
@@ -883,6 +1044,13 @@ type BrowserUpdateParams struct {
// Profile to load into the browser session. Only allowed if the session does not
// already have a profile loaded.
Profile shared.BrowserProfileParam `json:"profile,omitzero"`
+ // Proxy configuration to apply. Omit to leave the current configuration unchanged.
+ // Cannot be combined with proxy_id or disable_default_proxy. Set mode to direct to
+ // switch to direct egress regardless of stealth. Set mode to default to restore
+ // the browser default after using a selected proxy: Kernel's default stealth proxy
+ // for a stealth browser, or direct egress for a non-stealth browser. Updating
+ // proxy does not change stealth or CAPTCHA solver behavior.
+ Proxy BrowserProxyConfigParam `json:"proxy,omitzero"`
// User-defined key-value tags for the browser session. Omit to leave unchanged.
// Provide a map to replace the entire tag set (full replace, not a merge). Set to
// an empty object ({}) to clear all tags. Up to 50 pairs.
diff --git a/browser_test.go b/browser_test.go
index ee23508..57df42a 100644
--- a/browser_test.go
+++ b/browser_test.go
@@ -47,6 +47,11 @@ func TestBrowserNewWithOptionalParams(t *testing.T) {
Name: kernel.String("name"),
SaveChanges: kernel.Bool(true),
},
+ Proxy: kernel.BrowserProxyConfigParam{
+ ID: kernel.String("x"),
+ Mode: kernel.BrowserProxyModeDirect,
+ Name: kernel.String("x"),
+ },
ProxyID: kernel.String("proxy_id"),
StartURL: kernel.String("https://example.com"),
Stealth: kernel.Bool(true),
@@ -164,6 +169,11 @@ func TestBrowserUpdateWithOptionalParams(t *testing.T) {
Name: kernel.String("name"),
SaveChanges: kernel.Bool(true),
},
+ Proxy: kernel.BrowserProxyConfigParam{
+ ID: kernel.String("x"),
+ Mode: kernel.BrowserProxyModeDirect,
+ Name: kernel.String("x"),
+ },
ProxyID: kernel.String("proxy_id"),
Tags: kernel.Tags{
"team": "backend",
diff --git a/browserpool.go b/browserpool.go
index 641cc2d..cc3a240 100644
--- a/browserpool.go
+++ b/browserpool.go
@@ -363,7 +363,12 @@ type BrowserPoolAcquireResponse struct {
// Whether changes made during this browser session are saved back to its profile
// when the session ends. Omitted when no profile is attached.
ProfileSaveChanges bool `json:"profile_save_changes"`
- // ID of the proxy associated with this browser session, if any.
+ // Resolved proxy configuration for this browser session.
+ Proxy BrowserProxy `json:"proxy"`
+ // ID of the proxy associated with this browser session, if any. Deprecated in
+ // favor of proxy.
+ //
+ // Deprecated: deprecated
ProxyID string `json:"proxy_id"`
// URL the session was asked to navigate to on creation, if any. Recorded for
// debugging. Navigation is fire-and-forget — the URL is dispatched to the browser
@@ -410,6 +415,7 @@ type BrowserPoolAcquireResponse struct {
Pool respjson.Field
Profile respjson.Field
ProfileSaveChanges respjson.Field
+ Proxy respjson.Field
ProxyID respjson.Field
StartURL respjson.Field
Tags respjson.Field
diff --git a/invocation.go b/invocation.go
index a2bb44a..12b708d 100644
--- a/invocation.go
+++ b/invocation.go
@@ -577,7 +577,12 @@ type InvocationListBrowsersResponseBrowser struct {
// Whether changes made during this browser session are saved back to its profile
// when the session ends. Omitted when no profile is attached.
ProfileSaveChanges bool `json:"profile_save_changes"`
- // ID of the proxy associated with this browser session, if any.
+ // Resolved proxy configuration for this browser session.
+ Proxy BrowserProxy `json:"proxy"`
+ // ID of the proxy associated with this browser session, if any. Deprecated in
+ // favor of proxy.
+ //
+ // Deprecated: deprecated
ProxyID string `json:"proxy_id"`
// URL the session was asked to navigate to on creation, if any. Recorded for
// debugging. Navigation is fire-and-forget — the URL is dispatched to the browser
@@ -624,6 +629,7 @@ type InvocationListBrowsersResponseBrowser struct {
Pool respjson.Field
Profile respjson.Field
ProfileSaveChanges respjson.Field
+ Proxy respjson.Field
ProxyID respjson.Field
StartURL respjson.Field
Tags respjson.Field
From cd3e117dbbb8518688e2547de93da8ccf6f67089 Mon Sep 17 00:00:00 2001
From: "kernel-internal[bot]"
<260533166+kernel-internal[bot]@users.noreply.github.com>
Date: Sun, 9 Aug 2026 16:32:38 +0000
Subject: [PATCH 3/4] feat: Persist CUA-TS reauth blockers before failure
Stainless-Generated-From: 565691687ba43cd2d5fb88d72e0d25d506372cd6
---
authconnection.go | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/authconnection.go b/authconnection.go
index fcf5202..166884f 100644
--- a/authconnection.go
+++ b/authconnection.go
@@ -334,12 +334,15 @@ type ManagedAuth struct {
// automatically
// - `requires_email_code` — flow needs an email code that cannot be received
// automatically
+ // - `requires_customer_input` — flow needs another field or choice that is
+ // unavailable during unattended re-authentication
//
// Any of "external_credential", "cua_has_credential", "has_credential",
// "viable_plans_found", "no_requirements_recorded", "requirements_satisfiable",
// "no_prior_successful_login", "no_credential", "no_viable_plans",
// "viable_plans_require_external_action", "requires_external_action",
- // "requires_totp_without_secret", "requires_sms_code", "requires_email_code".
+ // "requires_totp_without_secret", "requires_sms_code", "requires_email_code",
+ // "requires_customer_input".
CanReauthReason ManagedAuthCanReauthReason `json:"can_reauth_reason"`
// Canonical choices awaiting selection. Prefer this over pending_sso_buttons,
// mfa_options, and sign_in_options when present.
@@ -629,6 +632,8 @@ func (r *ManagedAuthBrowserTelemetryExportOtlpDestination) UnmarshalJSON(data []
// automatically
// - `requires_email_code` — flow needs an email code that cannot be received
// automatically
+// - `requires_customer_input` — flow needs another field or choice that is
+// unavailable during unattended re-authentication
type ManagedAuthCanReauthReason string
const (
@@ -646,6 +651,7 @@ const (
ManagedAuthCanReauthReasonRequiresTotpWithoutSecret ManagedAuthCanReauthReason = "requires_totp_without_secret"
ManagedAuthCanReauthReasonRequiresSMSCode ManagedAuthCanReauthReason = "requires_sms_code"
ManagedAuthCanReauthReasonRequiresEmailCode ManagedAuthCanReauthReason = "requires_email_code"
+ ManagedAuthCanReauthReasonRequiresCustomerInput ManagedAuthCanReauthReason = "requires_customer_input"
)
// Canonical auth-flow choice awaiting user selection.
From 5819723ab49da6980dad983bd63ccc1565278e8c Mon Sep 17 00:00:00 2001
From: "kernel-internal[bot]"
<260533166+kernel-internal[bot]@users.noreply.github.com>
Date: Mon, 10 Aug 2026 16:33:28 +0000
Subject: [PATCH 4/4] feat: Managed auth: free-plan connections (cap 3),
credentials, 6h floor (packaging PR 5)
Stainless-Generated-From: b03c04a8bb6d23ef4f4c6c2ce046991524c168ca
---
authconnection.go | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/authconnection.go b/authconnection.go
index 166884f..5ee635c 100644
--- a/authconnection.go
+++ b/authconnection.go
@@ -386,9 +386,10 @@ type ManagedAuth struct {
FlowType ManagedAuthFlowType `json:"flow_type" api:"nullable"`
// Interval in seconds between automatic health checks. When set, the system
// periodically verifies the authentication status and triggers re-authentication
- // if needed. Maximum is 86400 (24 hours). Default is 3600 (1 hour). The minimum
- // depends on your plan: Enterprise: 300 (5 minutes), Startup: 1200 (20 minutes),
- // Hobbyist: 3600 (1 hour).
+ // if needed. Maximum is 86400 (24 hours). Default is 3600 (1 hour) or your plan
+ // minimum, whichever is larger. The minimum depends on your plan: Enterprise: 300
+ // (5 minutes), Startup: 1200 (20 minutes), Hobbyist: 3600 (1 hour), Free: 21600 (6
+ // hours).
HealthCheckInterval int64 `json:"health_check_interval" api:"nullable"`
// Whether periodic health checks are enabled for this connection. When false, the
// system will not automatically verify authentication status, and `auto_reauth`
@@ -1189,9 +1190,10 @@ type ManagedAuthCreateRequestParam struct {
AutoReauth param.Opt[bool] `json:"auto_reauth,omitzero"`
// Interval in seconds between automatic health checks. When set, the system
// periodically verifies the authentication status and triggers re-authentication
- // if needed. Maximum is 86400 (24 hours). Default is 3600 (1 hour). The minimum
- // depends on your plan: Enterprise: 300 (5 minutes), Startup: 1200 (20 minutes),
- // Hobbyist: 3600 (1 hour).
+ // if needed. Maximum is 86400 (24 hours). Default is 3600 (1 hour) or your plan
+ // minimum, whichever is larger. The minimum depends on your plan: Enterprise: 300
+ // (5 minutes), Startup: 1200 (20 minutes), Hobbyist: 3600 (1 hour), Free: 21600 (6
+ // hours).
HealthCheckInterval param.Opt[int64] `json:"health_check_interval,omitzero"`
// Whether to enable periodic health checks. When false, the system will not
// automatically verify authentication status, and `auto_reauth` has no effect on