From 20c19ef82dcaa4cb133ac5c520390ffccdc3cdfd Mon Sep 17 00:00:00 2001 From: boojack Date: Tue, 23 Jun 2026 00:04:54 +0800 Subject: [PATCH] feat(storage): add insecure_skip_tls_verify option for S3 Adds an opt-in toggle to skip TLS certificate verification when connecting to the S3 endpoint, for self-hosted S3-compatible backends (e.g. rustfs, MinIO) that use self-signed certificates. Exposed in both the store/API protos and the storage settings UI, mirroring the existing use_path_style toggle. When enabled, the AWS client uses an HTTP transport with InsecureSkipVerify; default behavior is unchanged. This governs backend-initiated S3 calls (uploads, deletes, thumbnails, and image/document streaming). Video/audio playback redirects the browser to a presigned URL, so that path still requires the browser to trust the cert. Closes #6039 --- internal/storage/s3/s3.go | 17 +++++++++++-- proto/api/v1/instance_service.proto | 4 ++++ proto/gen/api/v1/instance_service.pb.go | 24 ++++++++++++++----- proto/gen/openapi.yaml | 6 +++++ proto/gen/store/instance_setting.pb.go | 20 ++++++++++++---- proto/store/instance_setting.proto | 4 ++++ server/router/api/v1/instance_service.go | 22 +++++++++-------- .../components/Settings/StorageSection.tsx | 11 +++++++++ web/src/locales/en.json | 2 ++ .../types/proto/api/v1/instance_service_pb.ts | 11 ++++++++- 10 files changed, 98 insertions(+), 23 deletions(-) diff --git a/internal/storage/s3/s3.go b/internal/storage/s3/s3.go index 6d23b9e5..e91a160d 100644 --- a/internal/storage/s3/s3.go +++ b/internal/storage/s3/s3.go @@ -2,10 +2,13 @@ package s3 import ( "context" + "crypto/tls" "io" + "net/http" "time" "github.com/aws/aws-sdk-go-v2/aws" + awshttp "github.com/aws/aws-sdk-go-v2/aws/transport/http" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/credentials" "github.com/aws/aws-sdk-go-v2/service/s3" @@ -20,10 +23,20 @@ type Client struct { } func NewClient(ctx context.Context, s3Config *storepb.StorageS3Config) (*Client, error) { - cfg, err := config.LoadDefaultConfig(ctx, + loadOptions := []func(*config.LoadOptions) error{ config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(s3Config.AccessKeyId, s3Config.AccessKeySecret, "")), config.WithRegion(s3Config.Region), - ) + } + if s3Config.InsecureSkipTlsVerify { + // Skip TLS certificate verification for endpoints using self-signed certificates. + // This is opt-in and removes protection against man-in-the-middle attacks. + httpClient := awshttp.NewBuildableClient().WithTransportOptions(func(tr *http.Transport) { + tr.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} // #nosec G402 -- opt-in for self-signed S3 endpoints + }) + loadOptions = append(loadOptions, config.WithHTTPClient(httpClient)) + } + + cfg, err := config.LoadDefaultConfig(ctx, loadOptions...) if err != nil { return nil, errors.Wrap(err, "failed to load s3 config") } diff --git a/proto/api/v1/instance_service.proto b/proto/api/v1/instance_service.proto index 761b6a37..46ba8097 100644 --- a/proto/api/v1/instance_service.proto +++ b/proto/api/v1/instance_service.proto @@ -184,6 +184,10 @@ message InstanceSetting { string region = 4; string bucket = 5; bool use_path_style = 6; + // insecure_skip_tls_verify disables TLS certificate verification when connecting + // to the S3 endpoint. Only enable this for trusted endpoints that use a self-signed + // certificate; it removes protection against man-in-the-middle attacks. + bool insecure_skip_tls_verify = 7; } // The S3 config. S3Config s3_config = 4; diff --git a/proto/gen/api/v1/instance_service.pb.go b/proto/gen/api/v1/instance_service.pb.go index 8aad61ce..37e711cc 100644 --- a/proto/gen/api/v1/instance_service.pb.go +++ b/proto/gen/api/v1/instance_service.pb.go @@ -1541,8 +1541,12 @@ type InstanceSetting_StorageSetting_S3Config struct { Region string `protobuf:"bytes,4,opt,name=region,proto3" json:"region,omitempty"` Bucket string `protobuf:"bytes,5,opt,name=bucket,proto3" json:"bucket,omitempty"` UsePathStyle bool `protobuf:"varint,6,opt,name=use_path_style,json=usePathStyle,proto3" json:"use_path_style,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // insecure_skip_tls_verify disables TLS certificate verification when connecting + // to the S3 endpoint. Only enable this for trusted endpoints that use a self-signed + // certificate; it removes protection against man-in-the-middle attacks. + InsecureSkipTlsVerify bool `protobuf:"varint,7,opt,name=insecure_skip_tls_verify,json=insecureSkipTlsVerify,proto3" json:"insecure_skip_tls_verify,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *InstanceSetting_StorageSetting_S3Config) Reset() { @@ -1617,6 +1621,13 @@ func (x *InstanceSetting_StorageSetting_S3Config) GetUsePathStyle() bool { return false } +func (x *InstanceSetting_StorageSetting_S3Config) GetInsecureSkipTlsVerify() bool { + if x != nil { + return x.InsecureSkipTlsVerify + } + return false +} + // Email delivery configuration for notifications. type InstanceSetting_NotificationSetting_EmailSetting struct { state protoimpl.MessageState `protogen:"open.v1"` @@ -1802,7 +1813,7 @@ const file_api_v1_instance_service_proto_rawDesc = "" + "\x06commit\x18\b \x01(\tR\x06commit\x12\x1f\n" + "\vneeds_setup\x18\t \x01(\bR\n" + "needsSetup\"\x1b\n" + - "\x19GetInstanceProfileRequest\"\xcd\x1b\n" + + "\x19GetInstanceProfileRequest\"\x86\x1c\n" + "\x0fInstanceSetting\x12\x17\n" + "\x04name\x18\x01 \x01(\tB\x03\xe0A\bR\x04name\x12W\n" + "\x0fgeneral_setting\x18\x02 \x01(\v2,.memos.api.v1.InstanceSetting.GeneralSettingH\x00R\x0egeneralSetting\x12W\n" + @@ -1824,19 +1835,20 @@ const file_api_v1_instance_service_proto_rawDesc = "" + "\rCustomProfile\x12\x14\n" + "\x05title\x18\x01 \x01(\tR\x05title\x12 \n" + "\vdescription\x18\x02 \x01(\tR\vdescription\x12\x19\n" + - "\blogo_url\x18\x03 \x01(\tR\alogoUrl\x1a\xc1\x04\n" + + "\blogo_url\x18\x03 \x01(\tR\alogoUrl\x1a\xfa\x04\n" + "\x0eStorageSetting\x12[\n" + "\fstorage_type\x18\x01 \x01(\x0e28.memos.api.v1.InstanceSetting.StorageSetting.StorageTypeR\vstorageType\x12+\n" + "\x11filepath_template\x18\x02 \x01(\tR\x10filepathTemplate\x12/\n" + "\x14upload_size_limit_mb\x18\x03 \x01(\x03R\x11uploadSizeLimitMb\x12R\n" + - "\ts3_config\x18\x04 \x01(\v25.memos.api.v1.InstanceSetting.StorageSetting.S3ConfigR\bs3Config\x1a\xd1\x01\n" + + "\ts3_config\x18\x04 \x01(\v25.memos.api.v1.InstanceSetting.StorageSetting.S3ConfigR\bs3Config\x1a\x8a\x02\n" + "\bS3Config\x12\"\n" + "\raccess_key_id\x18\x01 \x01(\tR\vaccessKeyId\x12/\n" + "\x11access_key_secret\x18\x02 \x01(\tB\x03\xe0A\x04R\x0faccessKeySecret\x12\x1a\n" + "\bendpoint\x18\x03 \x01(\tR\bendpoint\x12\x16\n" + "\x06region\x18\x04 \x01(\tR\x06region\x12\x16\n" + "\x06bucket\x18\x05 \x01(\tR\x06bucket\x12$\n" + - "\x0euse_path_style\x18\x06 \x01(\bR\fusePathStyle\"L\n" + + "\x0euse_path_style\x18\x06 \x01(\bR\fusePathStyle\x127\n" + + "\x18insecure_skip_tls_verify\x18\a \x01(\bR\x15insecureSkipTlsVerify\"L\n" + "\vStorageType\x12\x1c\n" + "\x18STORAGE_TYPE_UNSPECIFIED\x10\x00\x12\f\n" + "\bDATABASE\x10\x01\x12\t\n" + diff --git a/proto/gen/openapi.yaml b/proto/gen/openapi.yaml index 8f35b0e1..25c7bba9 100644 --- a/proto/gen/openapi.yaml +++ b/proto/gen/openapi.yaml @@ -3627,6 +3627,12 @@ components: type: string usePathStyle: type: boolean + insecureSkipTlsVerify: + type: boolean + description: |- + insecure_skip_tls_verify disables TLS certificate verification when connecting + to the S3 endpoint. Only enable this for trusted endpoints that use a self-signed + certificate; it removes protection against man-in-the-middle attacks. description: |- S3 configuration for cloud storage backend. Reference: https://developers.cloudflare.com/r2/examples/aws/aws-sdk-go/ diff --git a/proto/gen/store/instance_setting.pb.go b/proto/gen/store/instance_setting.pb.go index 399b4dbe..263b289e 100644 --- a/proto/gen/store/instance_setting.pb.go +++ b/proto/gen/store/instance_setting.pb.go @@ -673,8 +673,12 @@ type StorageS3Config struct { Region string `protobuf:"bytes,4,opt,name=region,proto3" json:"region,omitempty"` Bucket string `protobuf:"bytes,5,opt,name=bucket,proto3" json:"bucket,omitempty"` UsePathStyle bool `protobuf:"varint,6,opt,name=use_path_style,json=usePathStyle,proto3" json:"use_path_style,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // insecure_skip_tls_verify disables TLS certificate verification when connecting + // to the S3 endpoint. Only enable this for trusted endpoints that use a self-signed + // certificate; it removes protection against man-in-the-middle attacks. + InsecureSkipTlsVerify bool `protobuf:"varint,7,opt,name=insecure_skip_tls_verify,json=insecureSkipTlsVerify,proto3" json:"insecure_skip_tls_verify,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *StorageS3Config) Reset() { @@ -749,6 +753,13 @@ func (x *StorageS3Config) GetUsePathStyle() bool { return false } +func (x *StorageS3Config) GetInsecureSkipTlsVerify() bool { + if x != nil { + return x.InsecureSkipTlsVerify + } + return false +} + type InstanceMemoRelatedSetting struct { state protoimpl.MessageState `protogen:"open.v1"` // content_length_limit is the limit of content length. Unit is byte. @@ -1338,14 +1349,15 @@ const file_store_instance_setting_proto_rawDesc = "" + "\x18STORAGE_TYPE_UNSPECIFIED\x10\x00\x12\f\n" + "\bDATABASE\x10\x01\x12\t\n" + "\x05LOCAL\x10\x02\x12\x06\n" + - "\x02S3\x10\x03\"\xd3\x01\n" + + "\x02S3\x10\x03\"\x8c\x02\n" + "\x0fStorageS3Config\x12\"\n" + "\raccess_key_id\x18\x01 \x01(\tR\vaccessKeyId\x12*\n" + "\x11access_key_secret\x18\x02 \x01(\tR\x0faccessKeySecret\x12\x1a\n" + "\bendpoint\x18\x03 \x01(\tR\bendpoint\x12\x16\n" + "\x06region\x18\x04 \x01(\tR\x06region\x12\x16\n" + "\x06bucket\x18\x05 \x01(\tR\x06bucket\x12$\n" + - "\x0euse_path_style\x18\x06 \x01(\bR\fusePathStyle\"\xc5\x01\n" + + "\x0euse_path_style\x18\x06 \x01(\bR\fusePathStyle\x127\n" + + "\x18insecure_skip_tls_verify\x18\a \x01(\bR\x15insecureSkipTlsVerify\"\xc5\x01\n" + "\x1aInstanceMemoRelatedSetting\x120\n" + "\x14content_length_limit\x18\x03 \x01(\x05R\x12contentLengthLimit\x127\n" + "\x18enable_double_click_edit\x18\x04 \x01(\bR\x15enableDoubleClickEdit\x12\x1c\n" + diff --git a/proto/store/instance_setting.proto b/proto/store/instance_setting.proto index c32ee708..be08b99f 100644 --- a/proto/store/instance_setting.proto +++ b/proto/store/instance_setting.proto @@ -100,6 +100,10 @@ message StorageS3Config { string region = 4; string bucket = 5; bool use_path_style = 6; + // insecure_skip_tls_verify disables TLS certificate verification when connecting + // to the S3 endpoint. Only enable this for trusted endpoints that use a self-signed + // certificate; it removes protection against man-in-the-middle attacks. + bool insecure_skip_tls_verify = 7; } message InstanceMemoRelatedSetting { diff --git a/server/router/api/v1/instance_service.go b/server/router/api/v1/instance_service.go index 7ab09b12..07999eae 100644 --- a/server/router/api/v1/instance_service.go +++ b/server/router/api/v1/instance_service.go @@ -444,10 +444,11 @@ func convertInstanceStorageSettingFromStore(settingpb *storepb.InstanceStorageSe setting.S3Config = &v1pb.InstanceSetting_StorageSetting_S3Config{ AccessKeyId: settingpb.S3Config.AccessKeyId, // AccessKeySecret is write-only: never returned in responses. - Endpoint: settingpb.S3Config.Endpoint, - Region: settingpb.S3Config.Region, - Bucket: settingpb.S3Config.Bucket, - UsePathStyle: settingpb.S3Config.UsePathStyle, + Endpoint: settingpb.S3Config.Endpoint, + Region: settingpb.S3Config.Region, + Bucket: settingpb.S3Config.Bucket, + UsePathStyle: settingpb.S3Config.UsePathStyle, + InsecureSkipTlsVerify: settingpb.S3Config.InsecureSkipTlsVerify, } } return setting @@ -464,12 +465,13 @@ func convertInstanceStorageSettingToStore(setting *v1pb.InstanceSetting_StorageS } if setting.S3Config != nil { settingpb.S3Config = &storepb.StorageS3Config{ - AccessKeyId: setting.S3Config.AccessKeyId, - AccessKeySecret: setting.S3Config.AccessKeySecret, - Endpoint: setting.S3Config.Endpoint, - Region: setting.S3Config.Region, - Bucket: setting.S3Config.Bucket, - UsePathStyle: setting.S3Config.UsePathStyle, + AccessKeyId: setting.S3Config.AccessKeyId, + AccessKeySecret: setting.S3Config.AccessKeySecret, + Endpoint: setting.S3Config.Endpoint, + Region: setting.S3Config.Region, + Bucket: setting.S3Config.Bucket, + UsePathStyle: setting.S3Config.UsePathStyle, + InsecureSkipTlsVerify: setting.S3Config.InsecureSkipTlsVerify, } } return settingpb diff --git a/web/src/components/Settings/StorageSection.tsx b/web/src/components/Settings/StorageSection.tsx index f54465e7..fc79947f 100644 --- a/web/src/components/Settings/StorageSection.tsx +++ b/web/src/components/Settings/StorageSection.tsx @@ -146,6 +146,7 @@ const StorageSection = () => { region: existing?.region ?? "", bucket: existing?.bucket ?? "", usePathStyle: existing?.usePathStyle ?? false, + insecureSkipTlsVerify: existing?.insecureSkipTlsVerify ?? false, [field]: value, }), }), @@ -332,6 +333,16 @@ const StorageSection = () => { onCheckedChange={(checked) => handleS3FieldChange("usePathStyle", checked)} /> + + + handleS3FieldChange("insecureSkipTlsVerify", checked)} + /> + )} diff --git a/web/src/locales/en.json b/web/src/locales/en.json index f850862f..16adf187 100644 --- a/web/src/locales/en.json +++ b/web/src/locales/en.json @@ -680,6 +680,8 @@ "endpoint-description": "Service endpoint, such as an AWS S3, Cloudflare R2, MinIO, or other compatible URL.", "filepath-template": "Filepath template", "filepath-template-description": "Used by local and S3 storage. Supports {timestamp}, {uuid}, and {filename}. Default: assets/{timestamp}_{uuid}_{filename}.", + "insecure-skip-tls-verify": "Skip TLS verification", + "insecure-skip-tls-verify-description": "Disable TLS certificate verification for the S3 endpoint. Enable only for trusted endpoints using a self-signed certificate; this removes protection against man-in-the-middle attacks.", "label": "Storage", "local-description": "Store new attachments on the server file system. This is the default for new instances.", "local-note-backup": "Persist and back up the attachment directory, especially in Docker or container deployments.", diff --git a/web/src/types/proto/api/v1/instance_service_pb.ts b/web/src/types/proto/api/v1/instance_service_pb.ts index 74b26c97..96567979 100644 --- a/web/src/types/proto/api/v1/instance_service_pb.ts +++ b/web/src/types/proto/api/v1/instance_service_pb.ts @@ -20,7 +20,7 @@ import type { Message } from "@bufbuild/protobuf"; * Describes the file api/v1/instance_service.proto. */ export const file_api_v1_instance_service: GenFile = /*@__PURE__*/ - fileDesc("Ch1hcGkvdjEvaW5zdGFuY2Vfc2VydmljZS5wcm90bxIMbWVtb3MuYXBpLnYxIo4BCg9JbnN0YW5jZVByb2ZpbGUSDwoHdmVyc2lvbhgCIAEoCRIMCgRkZW1vGAMgASgIEhQKDGluc3RhbmNlX3VybBgGIAEoCRIhCgVhZG1pbhgHIAEoCzISLm1lbW9zLmFwaS52MS5Vc2VyEg4KBmNvbW1pdBgIIAEoCRITCgtuZWVkc19zZXR1cBgJIAEoCCIbChlHZXRJbnN0YW5jZVByb2ZpbGVSZXF1ZXN0ItMVCg9JbnN0YW5jZVNldHRpbmcSEQoEbmFtZRgBIAEoCUID4EEIEkcKD2dlbmVyYWxfc2V0dGluZxgCIAEoCzIsLm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmcuR2VuZXJhbFNldHRpbmdIABJHCg9zdG9yYWdlX3NldHRpbmcYAyABKAsyLC5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nLlN0b3JhZ2VTZXR0aW5nSAASUAoUbWVtb19yZWxhdGVkX3NldHRpbmcYBCABKAsyMC5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nLk1lbW9SZWxhdGVkU2V0dGluZ0gAEkEKDHRhZ3Nfc2V0dGluZxgFIAEoCzIpLm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmcuVGFnc1NldHRpbmdIABJRChRub3RpZmljYXRpb25fc2V0dGluZxgGIAEoCzIxLm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmcuTm90aWZpY2F0aW9uU2V0dGluZ0gAEj0KCmFpX3NldHRpbmcYByABKAsyJy5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nLkFJU2V0dGluZ0gAGocDCg5HZW5lcmFsU2V0dGluZxIiChpkaXNhbGxvd191c2VyX3JlZ2lzdHJhdGlvbhgCIAEoCBIeChZkaXNhbGxvd19wYXNzd29yZF9hdXRoGAMgASgIEhkKEWFkZGl0aW9uYWxfc2NyaXB0GAQgASgJEhgKEGFkZGl0aW9uYWxfc3R5bGUYBSABKAkSUgoOY3VzdG9tX3Byb2ZpbGUYBiABKAsyOi5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nLkdlbmVyYWxTZXR0aW5nLkN1c3RvbVByb2ZpbGUSHQoVd2Vla19zdGFydF9kYXlfb2Zmc2V0GAcgASgFEiAKGGRpc2FsbG93X2NoYW5nZV91c2VybmFtZRgIIAEoCBIgChhkaXNhbGxvd19jaGFuZ2Vfbmlja25hbWUYCSABKAgaRQoNQ3VzdG9tUHJvZmlsZRINCgV0aXRsZRgBIAEoCRITCgtkZXNjcmlwdGlvbhgCIAEoCRIQCghsb2dvX3VybBgDIAEoCRq/AwoOU3RvcmFnZVNldHRpbmcSTgoMc3RvcmFnZV90eXBlGAEgASgOMjgubWVtb3MuYXBpLnYxLkluc3RhbmNlU2V0dGluZy5TdG9yYWdlU2V0dGluZy5TdG9yYWdlVHlwZRIZChFmaWxlcGF0aF90ZW1wbGF0ZRgCIAEoCRIcChR1cGxvYWRfc2l6ZV9saW1pdF9tYhgDIAEoAxJICglzM19jb25maWcYBCABKAsyNS5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nLlN0b3JhZ2VTZXR0aW5nLlMzQ29uZmlnGosBCghTM0NvbmZpZxIVCg1hY2Nlc3Nfa2V5X2lkGAEgASgJEh4KEWFjY2Vzc19rZXlfc2VjcmV0GAIgASgJQgPgQQQSEAoIZW5kcG9pbnQYAyABKAkSDgoGcmVnaW9uGAQgASgJEg4KBmJ1Y2tldBgFIAEoCRIWCg51c2VfcGF0aF9zdHlsZRgGIAEoCCJMCgtTdG9yYWdlVHlwZRIcChhTVE9SQUdFX1RZUEVfVU5TUEVDSUZJRUQQABIMCghEQVRBQkFTRRABEgkKBUxPQ0FMEAISBgoCUzMQAxqHAQoSTWVtb1JlbGF0ZWRTZXR0aW5nEhwKFGNvbnRlbnRfbGVuZ3RoX2xpbWl0GAMgASgFEiAKGGVuYWJsZV9kb3VibGVfY2xpY2tfZWRpdBgEIAEoCBIRCglyZWFjdGlvbnMYByADKAlKBAgCEANSGGRpc3BsYXlfd2l0aF91cGRhdGVfdGltZRpRCgtUYWdNZXRhZGF0YRIsChBiYWNrZ3JvdW5kX2NvbG9yGAEgASgLMhIuZ29vZ2xlLnR5cGUuQ29sb3ISFAoMYmx1cl9jb250ZW50GAIgASgIGqgBCgtUYWdzU2V0dGluZxJBCgR0YWdzGAEgAygLMjMubWVtb3MuYXBpLnYxLkluc3RhbmNlU2V0dGluZy5UYWdzU2V0dGluZy5UYWdzRW50cnkaVgoJVGFnc0VudHJ5EgsKA2tleRgBIAEoCRI4CgV2YWx1ZRgCIAEoCzIpLm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmcuVGFnTWV0YWRhdGE6AjgBGroCChNOb3RpZmljYXRpb25TZXR0aW5nEk0KBWVtYWlsGAEgASgLMj4ubWVtb3MuYXBpLnYxLkluc3RhbmNlU2V0dGluZy5Ob3RpZmljYXRpb25TZXR0aW5nLkVtYWlsU2V0dGluZxrTAQoMRW1haWxTZXR0aW5nEg8KB2VuYWJsZWQYASABKAgSEQoJc210cF9ob3N0GAIgASgJEhEKCXNtdHBfcG9ydBgDIAEoBRIVCg1zbXRwX3VzZXJuYW1lGAQgASgJEhoKDXNtdHBfcGFzc3dvcmQYBSABKAlCA+BBBBISCgpmcm9tX2VtYWlsGAYgASgJEhEKCWZyb21fbmFtZRgHIAEoCRIQCghyZXBseV90bxgIIAEoCRIPCgd1c2VfdGxzGAkgASgIEg8KB3VzZV9zc2wYCiABKAgamAEKCUFJU2V0dGluZxJBCglwcm92aWRlcnMYASADKAsyLi5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nLkFJUHJvdmlkZXJDb25maWcSSAoNdHJhbnNjcmlwdGlvbhgCIAEoCzIxLm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmcuVHJhbnNjcmlwdGlvbkNvbmZpZxrGAQoQQUlQcm92aWRlckNvbmZpZxIKCgJpZBgBIAEoCRINCgV0aXRsZRgCIAEoCRI6CgR0eXBlGAMgASgOMiwubWVtb3MuYXBpLnYxLkluc3RhbmNlU2V0dGluZy5BSVByb3ZpZGVyVHlwZRIQCghlbmRwb2ludBgEIAEoCRIUCgdhcGlfa2V5GAUgASgJQgPgQQQSGAoLYXBpX2tleV9zZXQYCCABKAhCA+BBAxIZCgxhcGlfa2V5X2hpbnQYCSABKAlCA+BBAxpbChNUcmFuc2NyaXB0aW9uQ29uZmlnEhMKC3Byb3ZpZGVyX2lkGAEgASgJEg0KBW1vZGVsGAIgASgJEhAKCGxhbmd1YWdlGAMgASgJEg4KBnByb21wdBgEIAEoCSJqCgNLZXkSEwoPS0VZX1VOU1BFQ0lGSUVEEAASCwoHR0VORVJBTBABEgsKB1NUT1JBR0UQAhIQCgxNRU1PX1JFTEFURUQQAxIICgRUQUdTEAQSEAoMTk9USUZJQ0FUSU9OEAUSBgoCQUkQBiJKCg5BSVByb3ZpZGVyVHlwZRIgChxBSV9QUk9WSURFUl9UWVBFX1VOU1BFQ0lGSUVEEAASCgoGT1BFTkFJEAESCgoGR0VNSU5JEAI6YepBXgocbWVtb3MuYXBpLnYxL0luc3RhbmNlU2V0dGluZxIbaW5zdGFuY2Uvc2V0dGluZ3Mve3NldHRpbmd9KhBpbnN0YW5jZVNldHRpbmdzMg9pbnN0YW5jZVNldHRpbmdCBwoFdmFsdWUiTwoZR2V0SW5zdGFuY2VTZXR0aW5nUmVxdWVzdBIyCgRuYW1lGAEgASgJQiTgQQL6QR4KHG1lbW9zLmFwaS52MS9JbnN0YW5jZVNldHRpbmciVgofQmF0Y2hHZXRJbnN0YW5jZVNldHRpbmdzUmVxdWVzdBIzCgVuYW1lcxgBIAMoCUIk4EEC+kEeChxtZW1vcy5hcGkudjEvSW5zdGFuY2VTZXR0aW5nIlMKIEJhdGNoR2V0SW5zdGFuY2VTZXR0aW5nc1Jlc3BvbnNlEi8KCHNldHRpbmdzGAEgAygLMh0ubWVtb3MuYXBpLnYxLkluc3RhbmNlU2V0dGluZyKJAQocVXBkYXRlSW5zdGFuY2VTZXR0aW5nUmVxdWVzdBIzCgdzZXR0aW5nGAEgASgLMh0ubWVtb3MuYXBpLnYxLkluc3RhbmNlU2V0dGluZ0ID4EECEjQKC3VwZGF0ZV9tYXNrGAIgASgLMhouZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFza0ID4EEBIpMBCh9UZXN0SW5zdGFuY2VFbWFpbFNldHRpbmdSZXF1ZXN0ElIKBWVtYWlsGAEgASgLMj4ubWVtb3MuYXBpLnYxLkluc3RhbmNlU2V0dGluZy5Ob3RpZmljYXRpb25TZXR0aW5nLkVtYWlsU2V0dGluZ0ID4EEBEhwKD3JlY2lwaWVudF9lbWFpbBgCIAEoCUID4EEBIhkKF0dldEluc3RhbmNlU3RhdHNSZXF1ZXN0ItIBCg1JbnN0YW5jZVN0YXRzEjsKCGRhdGFiYXNlGAEgASgLMikubWVtb3MuYXBpLnYxLkluc3RhbmNlU3RhdHMuRGF0YWJhc2VTdGF0cxIbChNsb2NhbF9zdG9yYWdlX2J5dGVzGAIgASgDEjIKDmdlbmVyYXRlZF90aW1lGAQgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBozCg1EYXRhYmFzZVN0YXRzEg4KBmRyaXZlchgBIAEoCRISCgpzaXplX2J5dGVzGAIgASgDMp8HCg9JbnN0YW5jZVNlcnZpY2USfgoSR2V0SW5zdGFuY2VQcm9maWxlEicubWVtb3MuYXBpLnYxLkdldEluc3RhbmNlUHJvZmlsZVJlcXVlc3QaHS5tZW1vcy5hcGkudjEuSW5zdGFuY2VQcm9maWxlIiCC0+STAhoSGC9hcGkvdjEvaW5zdGFuY2UvcHJvZmlsZRKPAQoSR2V0SW5zdGFuY2VTZXR0aW5nEicubWVtb3MuYXBpLnYxLkdldEluc3RhbmNlU2V0dGluZ1JlcXVlc3QaHS5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nIjHaQQRuYW1lgtPkkwIkEiIvYXBpL3YxL3tuYW1lPWluc3RhbmNlL3NldHRpbmdzLyp9EqgBChhCYXRjaEdldEluc3RhbmNlU2V0dGluZ3MSLS5tZW1vcy5hcGkudjEuQmF0Y2hHZXRJbnN0YW5jZVNldHRpbmdzUmVxdWVzdBouLm1lbW9zLmFwaS52MS5CYXRjaEdldEluc3RhbmNlU2V0dGluZ3NSZXNwb25zZSItgtPkkwInOgEqIiIvYXBpL3YxL2luc3RhbmNlL3NldHRpbmdzOmJhdGNoR2V0ErUBChVVcGRhdGVJbnN0YW5jZVNldHRpbmcSKi5tZW1vcy5hcGkudjEuVXBkYXRlSW5zdGFuY2VTZXR0aW5nUmVxdWVzdBodLm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmciUdpBE3NldHRpbmcsdXBkYXRlX21hc2uC0+STAjU6B3NldHRpbmcyKi9hcGkvdjEve3NldHRpbmcubmFtZT1pbnN0YW5jZS9zZXR0aW5ncy8qfRKeAQoYVGVzdEluc3RhbmNlRW1haWxTZXR0aW5nEi0ubWVtb3MuYXBpLnYxLlRlc3RJbnN0YW5jZUVtYWlsU2V0dGluZ1JlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiO4LT5JMCNToBKiIwL2FwaS92MS9pbnN0YW5jZS9zZXR0aW5ncy9ub3RpZmljYXRpb246dGVzdEVtYWlsEnYKEEdldEluc3RhbmNlU3RhdHMSJS5tZW1vcy5hcGkudjEuR2V0SW5zdGFuY2VTdGF0c1JlcXVlc3QaGy5tZW1vcy5hcGkudjEuSW5zdGFuY2VTdGF0cyIegtPkkwIYEhYvYXBpL3YxL2luc3RhbmNlL3N0YXRzQqwBChBjb20ubWVtb3MuYXBpLnYxQhRJbnN0YW5jZVNlcnZpY2VQcm90b1ABWjBnaXRodWIuY29tL3VzZW1lbW9zL21lbW9zL3Byb3RvL2dlbi9hcGkvdjE7YXBpdjGiAgNNQViqAgxNZW1vcy5BcGkuVjHKAgxNZW1vc1xBcGlcVjHiAhhNZW1vc1xBcGlcVjFcR1BCTWV0YWRhdGHqAg5NZW1vczo6QXBpOjpWMWIGcHJvdG8z", [file_api_v1_user_service, file_google_api_annotations, file_google_api_client, file_google_api_field_behavior, file_google_api_resource, file_google_protobuf_empty, file_google_protobuf_field_mask, file_google_protobuf_timestamp, file_google_type_color]); + fileDesc("Ch1hcGkvdjEvaW5zdGFuY2Vfc2VydmljZS5wcm90bxIMbWVtb3MuYXBpLnYxIo4BCg9JbnN0YW5jZVByb2ZpbGUSDwoHdmVyc2lvbhgCIAEoCRIMCgRkZW1vGAMgASgIEhQKDGluc3RhbmNlX3VybBgGIAEoCRIhCgVhZG1pbhgHIAEoCzISLm1lbW9zLmFwaS52MS5Vc2VyEg4KBmNvbW1pdBgIIAEoCRITCgtuZWVkc19zZXR1cBgJIAEoCCIbChlHZXRJbnN0YW5jZVByb2ZpbGVSZXF1ZXN0IvUVCg9JbnN0YW5jZVNldHRpbmcSEQoEbmFtZRgBIAEoCUID4EEIEkcKD2dlbmVyYWxfc2V0dGluZxgCIAEoCzIsLm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmcuR2VuZXJhbFNldHRpbmdIABJHCg9zdG9yYWdlX3NldHRpbmcYAyABKAsyLC5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nLlN0b3JhZ2VTZXR0aW5nSAASUAoUbWVtb19yZWxhdGVkX3NldHRpbmcYBCABKAsyMC5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nLk1lbW9SZWxhdGVkU2V0dGluZ0gAEkEKDHRhZ3Nfc2V0dGluZxgFIAEoCzIpLm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmcuVGFnc1NldHRpbmdIABJRChRub3RpZmljYXRpb25fc2V0dGluZxgGIAEoCzIxLm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmcuTm90aWZpY2F0aW9uU2V0dGluZ0gAEj0KCmFpX3NldHRpbmcYByABKAsyJy5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nLkFJU2V0dGluZ0gAGocDCg5HZW5lcmFsU2V0dGluZxIiChpkaXNhbGxvd191c2VyX3JlZ2lzdHJhdGlvbhgCIAEoCBIeChZkaXNhbGxvd19wYXNzd29yZF9hdXRoGAMgASgIEhkKEWFkZGl0aW9uYWxfc2NyaXB0GAQgASgJEhgKEGFkZGl0aW9uYWxfc3R5bGUYBSABKAkSUgoOY3VzdG9tX3Byb2ZpbGUYBiABKAsyOi5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nLkdlbmVyYWxTZXR0aW5nLkN1c3RvbVByb2ZpbGUSHQoVd2Vla19zdGFydF9kYXlfb2Zmc2V0GAcgASgFEiAKGGRpc2FsbG93X2NoYW5nZV91c2VybmFtZRgIIAEoCBIgChhkaXNhbGxvd19jaGFuZ2Vfbmlja25hbWUYCSABKAgaRQoNQ3VzdG9tUHJvZmlsZRINCgV0aXRsZRgBIAEoCRITCgtkZXNjcmlwdGlvbhgCIAEoCRIQCghsb2dvX3VybBgDIAEoCRrhAwoOU3RvcmFnZVNldHRpbmcSTgoMc3RvcmFnZV90eXBlGAEgASgOMjgubWVtb3MuYXBpLnYxLkluc3RhbmNlU2V0dGluZy5TdG9yYWdlU2V0dGluZy5TdG9yYWdlVHlwZRIZChFmaWxlcGF0aF90ZW1wbGF0ZRgCIAEoCRIcChR1cGxvYWRfc2l6ZV9saW1pdF9tYhgDIAEoAxJICglzM19jb25maWcYBCABKAsyNS5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nLlN0b3JhZ2VTZXR0aW5nLlMzQ29uZmlnGq0BCghTM0NvbmZpZxIVCg1hY2Nlc3Nfa2V5X2lkGAEgASgJEh4KEWFjY2Vzc19rZXlfc2VjcmV0GAIgASgJQgPgQQQSEAoIZW5kcG9pbnQYAyABKAkSDgoGcmVnaW9uGAQgASgJEg4KBmJ1Y2tldBgFIAEoCRIWCg51c2VfcGF0aF9zdHlsZRgGIAEoCBIgChhpbnNlY3VyZV9za2lwX3Rsc192ZXJpZnkYByABKAgiTAoLU3RvcmFnZVR5cGUSHAoYU1RPUkFHRV9UWVBFX1VOU1BFQ0lGSUVEEAASDAoIREFUQUJBU0UQARIJCgVMT0NBTBACEgYKAlMzEAMahwEKEk1lbW9SZWxhdGVkU2V0dGluZxIcChRjb250ZW50X2xlbmd0aF9saW1pdBgDIAEoBRIgChhlbmFibGVfZG91YmxlX2NsaWNrX2VkaXQYBCABKAgSEQoJcmVhY3Rpb25zGAcgAygJSgQIAhADUhhkaXNwbGF5X3dpdGhfdXBkYXRlX3RpbWUaUQoLVGFnTWV0YWRhdGESLAoQYmFja2dyb3VuZF9jb2xvchgBIAEoCzISLmdvb2dsZS50eXBlLkNvbG9yEhQKDGJsdXJfY29udGVudBgCIAEoCBqoAQoLVGFnc1NldHRpbmcSQQoEdGFncxgBIAMoCzIzLm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmcuVGFnc1NldHRpbmcuVGFnc0VudHJ5GlYKCVRhZ3NFbnRyeRILCgNrZXkYASABKAkSOAoFdmFsdWUYAiABKAsyKS5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nLlRhZ01ldGFkYXRhOgI4ARq6AgoTTm90aWZpY2F0aW9uU2V0dGluZxJNCgVlbWFpbBgBIAEoCzI+Lm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmcuTm90aWZpY2F0aW9uU2V0dGluZy5FbWFpbFNldHRpbmca0wEKDEVtYWlsU2V0dGluZxIPCgdlbmFibGVkGAEgASgIEhEKCXNtdHBfaG9zdBgCIAEoCRIRCglzbXRwX3BvcnQYAyABKAUSFQoNc210cF91c2VybmFtZRgEIAEoCRIaCg1zbXRwX3Bhc3N3b3JkGAUgASgJQgPgQQQSEgoKZnJvbV9lbWFpbBgGIAEoCRIRCglmcm9tX25hbWUYByABKAkSEAoIcmVwbHlfdG8YCCABKAkSDwoHdXNlX3RscxgJIAEoCBIPCgd1c2Vfc3NsGAogASgIGpgBCglBSVNldHRpbmcSQQoJcHJvdmlkZXJzGAEgAygLMi4ubWVtb3MuYXBpLnYxLkluc3RhbmNlU2V0dGluZy5BSVByb3ZpZGVyQ29uZmlnEkgKDXRyYW5zY3JpcHRpb24YAiABKAsyMS5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nLlRyYW5zY3JpcHRpb25Db25maWcaxgEKEEFJUHJvdmlkZXJDb25maWcSCgoCaWQYASABKAkSDQoFdGl0bGUYAiABKAkSOgoEdHlwZRgDIAEoDjIsLm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmcuQUlQcm92aWRlclR5cGUSEAoIZW5kcG9pbnQYBCABKAkSFAoHYXBpX2tleRgFIAEoCUID4EEEEhgKC2FwaV9rZXlfc2V0GAggASgIQgPgQQMSGQoMYXBpX2tleV9oaW50GAkgASgJQgPgQQMaWwoTVHJhbnNjcmlwdGlvbkNvbmZpZxITCgtwcm92aWRlcl9pZBgBIAEoCRINCgVtb2RlbBgCIAEoCRIQCghsYW5ndWFnZRgDIAEoCRIOCgZwcm9tcHQYBCABKAkiagoDS2V5EhMKD0tFWV9VTlNQRUNJRklFRBAAEgsKB0dFTkVSQUwQARILCgdTVE9SQUdFEAISEAoMTUVNT19SRUxBVEVEEAMSCAoEVEFHUxAEEhAKDE5PVElGSUNBVElPThAFEgYKAkFJEAYiSgoOQUlQcm92aWRlclR5cGUSIAocQUlfUFJPVklERVJfVFlQRV9VTlNQRUNJRklFRBAAEgoKBk9QRU5BSRABEgoKBkdFTUlOSRACOmHqQV4KHG1lbW9zLmFwaS52MS9JbnN0YW5jZVNldHRpbmcSG2luc3RhbmNlL3NldHRpbmdzL3tzZXR0aW5nfSoQaW5zdGFuY2VTZXR0aW5nczIPaW5zdGFuY2VTZXR0aW5nQgcKBXZhbHVlIk8KGUdldEluc3RhbmNlU2V0dGluZ1JlcXVlc3QSMgoEbmFtZRgBIAEoCUIk4EEC+kEeChxtZW1vcy5hcGkudjEvSW5zdGFuY2VTZXR0aW5nIlYKH0JhdGNoR2V0SW5zdGFuY2VTZXR0aW5nc1JlcXVlc3QSMwoFbmFtZXMYASADKAlCJOBBAvpBHgocbWVtb3MuYXBpLnYxL0luc3RhbmNlU2V0dGluZyJTCiBCYXRjaEdldEluc3RhbmNlU2V0dGluZ3NSZXNwb25zZRIvCghzZXR0aW5ncxgBIAMoCzIdLm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmciiQEKHFVwZGF0ZUluc3RhbmNlU2V0dGluZ1JlcXVlc3QSMwoHc2V0dGluZxgBIAEoCzIdLm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmdCA+BBAhI0Cgt1cGRhdGVfbWFzaxgCIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2tCA+BBASKTAQofVGVzdEluc3RhbmNlRW1haWxTZXR0aW5nUmVxdWVzdBJSCgVlbWFpbBgBIAEoCzI+Lm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmcuTm90aWZpY2F0aW9uU2V0dGluZy5FbWFpbFNldHRpbmdCA+BBARIcCg9yZWNpcGllbnRfZW1haWwYAiABKAlCA+BBASIZChdHZXRJbnN0YW5jZVN0YXRzUmVxdWVzdCLSAQoNSW5zdGFuY2VTdGF0cxI7CghkYXRhYmFzZRgBIAEoCzIpLm1lbW9zLmFwaS52MS5JbnN0YW5jZVN0YXRzLkRhdGFiYXNlU3RhdHMSGwoTbG9jYWxfc3RvcmFnZV9ieXRlcxgCIAEoAxIyCg5nZW5lcmF0ZWRfdGltZRgEIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXAaMwoNRGF0YWJhc2VTdGF0cxIOCgZkcml2ZXIYASABKAkSEgoKc2l6ZV9ieXRlcxgCIAEoAzKfBwoPSW5zdGFuY2VTZXJ2aWNlEn4KEkdldEluc3RhbmNlUHJvZmlsZRInLm1lbW9zLmFwaS52MS5HZXRJbnN0YW5jZVByb2ZpbGVSZXF1ZXN0Gh0ubWVtb3MuYXBpLnYxLkluc3RhbmNlUHJvZmlsZSIggtPkkwIaEhgvYXBpL3YxL2luc3RhbmNlL3Byb2ZpbGUSjwEKEkdldEluc3RhbmNlU2V0dGluZxInLm1lbW9zLmFwaS52MS5HZXRJbnN0YW5jZVNldHRpbmdSZXF1ZXN0Gh0ubWVtb3MuYXBpLnYxLkluc3RhbmNlU2V0dGluZyIx2kEEbmFtZYLT5JMCJBIiL2FwaS92MS97bmFtZT1pbnN0YW5jZS9zZXR0aW5ncy8qfRKoAQoYQmF0Y2hHZXRJbnN0YW5jZVNldHRpbmdzEi0ubWVtb3MuYXBpLnYxLkJhdGNoR2V0SW5zdGFuY2VTZXR0aW5nc1JlcXVlc3QaLi5tZW1vcy5hcGkudjEuQmF0Y2hHZXRJbnN0YW5jZVNldHRpbmdzUmVzcG9uc2UiLYLT5JMCJzoBKiIiL2FwaS92MS9pbnN0YW5jZS9zZXR0aW5nczpiYXRjaEdldBK1AQoVVXBkYXRlSW5zdGFuY2VTZXR0aW5nEioubWVtb3MuYXBpLnYxLlVwZGF0ZUluc3RhbmNlU2V0dGluZ1JlcXVlc3QaHS5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nIlHaQRNzZXR0aW5nLHVwZGF0ZV9tYXNrgtPkkwI1OgdzZXR0aW5nMiovYXBpL3YxL3tzZXR0aW5nLm5hbWU9aW5zdGFuY2Uvc2V0dGluZ3MvKn0SngEKGFRlc3RJbnN0YW5jZUVtYWlsU2V0dGluZxItLm1lbW9zLmFwaS52MS5UZXN0SW5zdGFuY2VFbWFpbFNldHRpbmdSZXF1ZXN0GhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5IjuC0+STAjU6ASoiMC9hcGkvdjEvaW5zdGFuY2Uvc2V0dGluZ3Mvbm90aWZpY2F0aW9uOnRlc3RFbWFpbBJ2ChBHZXRJbnN0YW5jZVN0YXRzEiUubWVtb3MuYXBpLnYxLkdldEluc3RhbmNlU3RhdHNSZXF1ZXN0GhsubWVtb3MuYXBpLnYxLkluc3RhbmNlU3RhdHMiHoLT5JMCGBIWL2FwaS92MS9pbnN0YW5jZS9zdGF0c0KsAQoQY29tLm1lbW9zLmFwaS52MUIUSW5zdGFuY2VTZXJ2aWNlUHJvdG9QAVowZ2l0aHViLmNvbS91c2VtZW1vcy9tZW1vcy9wcm90by9nZW4vYXBpL3YxO2FwaXYxogIDTUFYqgIMTWVtb3MuQXBpLlYxygIMTWVtb3NcQXBpXFYx4gIYTWVtb3NcQXBpXFYxXEdQQk1ldGFkYXRh6gIOTWVtb3M6OkFwaTo6VjFiBnByb3RvMw", [file_api_v1_user_service, file_google_api_annotations, file_google_api_client, file_google_api_field_behavior, file_google_api_resource, file_google_protobuf_empty, file_google_protobuf_field_mask, file_google_protobuf_timestamp, file_google_type_color]); /** * Instance profile message containing basic instance information. @@ -341,6 +341,15 @@ export type InstanceSetting_StorageSetting_S3Config = Message<"memos.api.v1.Inst * @generated from field: bool use_path_style = 6; */ usePathStyle: boolean; + + /** + * insecure_skip_tls_verify disables TLS certificate verification when connecting + * to the S3 endpoint. Only enable this for trusted endpoints that use a self-signed + * certificate; it removes protection against man-in-the-middle attacks. + * + * @generated from field: bool insecure_skip_tls_verify = 7; + */ + insecureSkipTlsVerify: boolean; }; /**