Files
trufflehog/proto/sources.proto
Shahzad Haider 54ff78b9a8 Object filtering in S3 (#5286)
* Add S3 object filtering fields to the sources proto

* Skip S3 objects by key prefix or file extension before downloading them

* Document the S3 source and how to narrow a scan to specific objects

* Trim filter entries and report when a filter excludes every object

* Document the S3 object filter edge cases and listing cost

* Align S3 object filter logging with the logging RFC

* Simplify S3 extension matching and always log a fully filtered bucket
2026-09-09 14:31:29 +05:00

587 lines
17 KiB
Protocol Buffer

syntax = "proto3";
package sources;
option go_package = "github.com/trufflesecurity/trufflehog/v3/pkg/pb/sourcespb";
import "validate/validate.proto";
import "credentials.proto";
import "google/protobuf/any.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";
enum SourceType {
SOURCE_TYPE_AZURE_STORAGE = 0;
SOURCE_TYPE_BITBUCKET = 1;
SOURCE_TYPE_CIRCLECI = 2;
SOURCE_TYPE_CONFLUENCE = 3;
SOURCE_TYPE_DOCKER = 4;
SOURCE_TYPE_ECR = 5;
SOURCE_TYPE_GCS = 6;
SOURCE_TYPE_GITHUB = 7;
SOURCE_TYPE_PUBLIC_GIT = 8;
SOURCE_TYPE_GITLAB = 9;
SOURCE_TYPE_JIRA = 10;
SOURCE_TYPE_NPM_UNAUTHD_PACKAGES = 11;
SOURCE_TYPE_PYPI_UNAUTHD_PACKAGES = 12;
SOURCE_TYPE_S3 = 13;
SOURCE_TYPE_SLACK = 14;
SOURCE_TYPE_FILESYSTEM = 15;
SOURCE_TYPE_GIT = 16;
SOURCE_TYPE_TEST = 17;
SOURCE_TYPE_S3_UNAUTHED = 18;
SOURCE_TYPE_GITHUB_UNAUTHENTICATED_ORG = 19;
SOURCE_TYPE_BUILDKITE = 20;
SOURCE_TYPE_GERRIT = 21;
SOURCE_TYPE_JENKINS = 22;
SOURCE_TYPE_TEAMS = 23;
SOURCE_TYPE_JFROG_ARTIFACTORY = 24;
SOURCE_TYPE_SYSLOG = 25;
SOURCE_TYPE_PUBLIC_EVENT_MONITORING = 26;
SOURCE_TYPE_SLACK_REALTIME = 27;
SOURCE_TYPE_GOOGLE_DRIVE = 28;
SOURCE_TYPE_SHAREPOINT = 29;
SOURCE_TYPE_GCS_UNAUTHED = 30;
SOURCE_TYPE_AZURE_REPOS = 31;
SOURCE_TYPE_TRAVISCI = 32;
SOURCE_TYPE_POSTMAN = 33;
SOURCE_TYPE_WEBHOOK = 34;
SOURCE_TYPE_ELASTICSEARCH = 35;
SOURCE_TYPE_HUGGINGFACE = 36;
SOURCE_TYPE_GITHUB_EXPERIMENTAL = 37;
SOURCE_TYPE_SENTRY = 38;
SOURCE_TYPE_GITHUB_REALTIME = 39;
SOURCE_TYPE_STDIN = 40;
SOURCE_TYPE_SLACK_CONTINUOUS = 41;
SOURCE_TYPE_JSON_ENUMERATOR = 42;
SOURCE_TYPE_AWS_SECRETS_MANAGER = 43;
}
message LocalSource {
string type = 1 ;
string name = 2 ;
// DEPRECATED: scan_interval is deprecated and can be removed when we no longer depend on the name.
// Deprecating in favor of scan_period due to the fact that scan_interval is a duration
// which is a fixed-length span of time represented as a count of seconds and fractions of seconds
// at nanosecond resolution. Most of the time, we want to be able to specify a scan interval in
// human-readable format (e.g. 45s, 30m, 12h, etc.) which is not possible with a duration.
// https://protobuf.dev/reference/protobuf/google.protobuf/#duration
google.protobuf.Duration scan_interval = 3 [deprecated = true];
bool verify = 4;
google.protobuf.Any connection = 5;
string scan_period = 6;
}
// https://www.jfrog.com/confluence/display/JFROG/Artifactory+REST+API#ArtifactoryRESTAPI-RetrieveFolderorRepositoryArchive
message Artifactory {
string endpoint = 1 [(validate.rules).string.uri_ref = true];
oneof credential {
credentials.BasicAuth basic_auth = 2;
string access_token = 3;
credentials.Unauthenticated unauthenticated = 7;
}
repeated string repositories = 4;
repeated string include_paths = 5;
repeated string ignore_paths = 6;
}
message AzureStorage {
oneof credential {
string connection_string = 1;
credentials.BasicAuth basic_auth = 2;
string client_certificate = 3;
credentials.Unauthenticated unauthenticated = 4;
}
repeated string storage_containers = 5;
}
enum BitbucketInstallationType {
AUTODETECT = 0;
CLOUD = 1;
DATA_CENTER = 2;
}
message Bitbucket {
string endpoint = 1 [(validate.rules).string.uri_ref = true];
oneof credential {
string token = 2;
credentials.Oauth2 oauth = 3;
credentials.BasicAuth basic_auth = 4;
credentials.BitbucketApiToken api_token = 14;
}
repeated string repositories = 5;
repeated string ignore_repos = 6;
bool skip_binaries = 7;
bool skip_archives = 8;
BitbucketInstallationType installation_type = 9;
string oauth_authorization_endpoint = 10; // endpoint for OAuth authorization flow in Bitbucket Data Center application links
string oauth_token_endpoint = 11; // endpoint for getting OAuth access/refresh tokens in Bitbucket Data Center application links
repeated string oauth_scopes = 12; // list of OAuth scopes that the access token is provided
bool allow_secrets_manager_write = 13; // flag to explicitly allow TruffleHog to write to the user's secrets manager
}
message CircleCI {
string endpoint = 1 [(validate.rules).string.uri_ref = true];
oneof credential {
string token = 2;
}
}
message TravisCI {
string endpoint = 1 [(validate.rules).string.uri_ref = true];
oneof credential {
string token = 2;
}
}
message Confluence {
string endpoint = 1 [(validate.rules).string.uri_ref = true];
oneof credential {
credentials.Unauthenticated unauthenticated = 2;
credentials.BasicAuth basic_auth = 3;
string token = 4;
}
enum GetAllSpacesScope {
ALL = 0;
GLOBAL = 1;
PERSONAL = 2;
}
GetAllSpacesScope spaces_scope = 5;
bool insecure_skip_verify_tls = 6;
repeated string spaces = 7;
repeated string ignore_spaces = 8;
bool include_attachments = 9;
bool skip_history = 10;
bool include_comments = 11;
}
message Docker {
oneof credential {
credentials.Unauthenticated unauthenticated = 1;
credentials.BasicAuth basic_auth = 2;
string bearer_token = 3;
bool docker_keychain = 4;
}
repeated string images = 5;
repeated string exclude_paths = 6;
string namespace = 7;
string registry_token = 8;
}
message ECR {
oneof credential {
credentials.KeySecret access_key = 1;
}
repeated string registries = 2;
}
message Filesystem {
// DEPRECATED: directories is deprecated and can be removed / renamed to
// paths when we no longer depend on the name in enterprise configs.
repeated string directories = 1;
repeated string paths = 2;
string include_paths_file = 3; // path to file containing newline separated list of paths
string exclude_paths_file = 4; // path to file containing newline separated list of paths
bool skip_binaries = 5; // allows skipping binary files from the scan
int32 max_symlink_depth = 6; // allows following symlinks upto specified max depth
}
message GCS {
oneof credential {
string json_service_account = 1;
string api_key = 2;
credentials.Unauthenticated unauthenticated = 3;
credentials.CloudEnvironment adc = 4;
string service_account_file = 11;
credentials.Oauth2 oauth = 12;
}
string project_id = 5;
repeated string include_buckets = 6;
repeated string exclude_buckets = 7;
repeated string include_objects = 8;
repeated string exclude_objects = 9;
int64 max_object_size = 10;
}
message Git {
oneof credential {
credentials.BasicAuth basic_auth = 1;
credentials.Unauthenticated unauthenticated = 2;
credentials.SSHAuth ssh_auth = 5;
}
repeated string directories = 3;
repeated string repositories = 4;
string head = 6;
string base = 7;
bool bare = 8;
string include_paths_file = 9; // path to file containing newline separated list of paths
string exclude_paths_file = 10; // path to file containing newline separated list of paths
string exclude_globs = 11; // comma separated list of globs
int64 max_depth = 12;
// This field is generally used by the CLI or within CI/CD systems to specify a single repository,
// whereas the repositories field is used by the enterprise config to specify multiple repositories.
// Passing a single repository via the uri field also allows for additional options to be specified
// like head, base, bare, etc.
string uri = 13; // repository URL. https://, file://, or ssh://
bool skip_binaries = 14;
bool skip_archives = 15;
string clone_path = 16;
bool no_cleanup = 17;
bool print_legacy_json = 18;
bool trust_local_git_config = 19; // Trust local git configurations
}
message GitLab {
string endpoint = 1 [(validate.rules).string.uri_ref = true];
oneof credential {
string token = 2;
credentials.Oauth2 oauth = 3;
credentials.BasicAuth basic_auth = 4;
}
repeated string repositories = 5;
repeated string ignore_repos = 6;
bool skip_binaries = 7;
bool skip_archives = 8;
repeated string include_repos = 9;
bool exclude_projects_shared_into_groups = 10;
bool remove_auth_in_url = 11;
repeated string group_ids = 12;
string clone_path = 13;
bool no_cleanup = 14;
bool print_legacy_json = 15;
}
message GitHub {
string endpoint = 1 [(validate.rules).string.uri_ref = true];
oneof credential {
credentials.GitHubApp github_app = 2;
string token = 3;
credentials.Unauthenticated unauthenticated = 4;
credentials.BasicAuth basic_auth = 13;
}
repeated string repositories = 5;
repeated string organizations = 6;
bool scanUsers = 7;
bool includeForks = 8;
string head = 9;
string base = 10;
repeated string ignore_repos = 11;
repeated string include_repos = 12;
bool include_pull_request_comments = 14;
bool include_issue_comments = 15;
bool include_gist_comments = 16;
bool skip_binaries = 17;
bool skip_archives = 18;
bool include_wikis = 19;
uint32 comments_timeframe_days = 20;
bool remove_auth_in_url = 21;
string clone_path = 22;
bool no_cleanup = 23;
bool ignore_gists = 24;
bool print_legacy_json = 25;
// When using GitHub App credentials, enumerate repositories from every app installation.
bool scan_all_installations = 26;
bool exclude_archived = 27;
}
message GitHubExperimental {
string repository = 1;
oneof credential {
string token = 2;
}
bool object_discovery = 3;
int64 collision_threshold = 4;
bool delete_cached_data = 5;
}
message GitHubRealtime {
uint32 listener_port = 1;
string webhook_secret = 2;
string endpoint = 3 [(validate.rules).string.uri_ref = true];
oneof credential {
credentials.GitHubApp github_app = 4;
string token = 5;
credentials.Unauthenticated unauthenticated = 6;
credentials.BasicAuth basic_auth = 7;
}
}
message GoogleDrive {
oneof credential {
string refresh_token = 1;
bool use_token_service = 2;
credentials.Oauth2 oauth = 3; // on-prem scanning
credentials.GoogleDriveDWD dwd = 4; // Domain-Wide Delegation
}
}
message Huggingface {
string endpoint = 1 [(validate.rules).string.uri_ref = true];
oneof credential {
string token = 2;
credentials.Unauthenticated unauthenticated = 3;
}
repeated string models = 4;
repeated string spaces = 5;
repeated string datasets = 12;
repeated string organizations = 6;
repeated string users = 15;
repeated string ignore_models = 7;
repeated string include_models = 8;
repeated string ignore_spaces = 9;
repeated string include_spaces = 10;
repeated string ignore_datasets = 13;
repeated string include_datasets = 14;
bool skip_all_models = 16;
bool skip_all_spaces = 17;
bool skip_all_datasets = 18;
bool include_discussions = 11;
bool include_prs = 19;
repeated string buckets = 20;
repeated string ignore_buckets = 21;
repeated string include_buckets = 22;
bool skip_all_buckets = 23;
}
enum JiraInstallationType {
JIRA_INSTALLATION_TYPE_AUTODETECT = 0;
JIRA_INSTALLATION_TYPE_CLOUD = 1;
JIRA_INSTALLATION_TYPE_DATA_CENTER = 2;
}
message JIRA {
string endpoint = 1 [(validate.rules).string.uri_ref = true];
oneof credential {
credentials.BasicAuth basic_auth = 2;
credentials.Unauthenticated unauthenticated = 3;
credentials.Oauth2 oauth = 4;
string token = 6;
}
repeated string projects = 5;
repeated string ignore_projects = 7;
bool insecure_skip_verify_tls = 8;
// Override autodetection of Jira installation type.
// Defaults to AUTODETECT which checks for cloud-only endpoints.
JiraInstallationType installation_type = 9;
}
message NPMUnauthenticatedPackage {
oneof credential {
credentials.Unauthenticated unauthenticated = 1;
}
}
message PyPIUnauthenticatedPackage {
oneof credential {
credentials.Unauthenticated unauthenticated = 1;
}
}
message S3 {
oneof credential {
credentials.KeySecret access_key = 1;
credentials.Unauthenticated unauthenticated = 2;
credentials.CloudEnvironment cloud_environment = 4;
credentials.AWSSessionTokenSecret session_token = 5;
}
repeated string buckets = 3;
int64 max_object_size = 6;
repeated string roles = 7;
repeated string ignore_buckets = 8;
bool enable_resumption = 9 [deprecated = true];
// endpoint targets an S3-compatible service other than AWS S3. When set,
// per-bucket region discovery is skipped because it is an AWS-only API.
string endpoint = 10 [(validate.rules).string.uri_ref = true];
// region is the region used to sign requests. Defaults to us-east-1.
string region = 11;
// include_prefixes limits the scan to objects whose key matches one of these
// key prefixes. Leave empty to consider every object in the bucket.
repeated string include_prefixes = 12;
// exclude_prefixes skips objects whose key matches one of these key prefixes.
repeated string exclude_prefixes = 13;
// include_extensions limits the scan to objects whose key ends in one of these
// file extensions, written without a leading dot (e.g. "tf", "yaml"). Leave
// empty to consider every extension. Cannot be combined with
// exclude_extensions.
repeated string include_extensions = 14;
// exclude_extensions skips objects whose key ends in one of these file
// extensions, written without a leading dot (e.g. "zip", "mp4"). Cannot be
// combined with include_extensions.
repeated string exclude_extensions = 15;
}
message Slack {
string endpoint = 1 [(validate.rules).string.uri_ref = true];
oneof credential {
string token = 2;
credentials.SlackTokens tokens = 5;
}
repeated string channels = 3;
repeated string ignore_list = 4;
}
message Test{}
message Buildkite {
oneof credential {
string token = 1;
}
}
message Gerrit {
string endpoint = 1 [(validate.rules).string.uri_ref = true];
oneof credential {
credentials.BasicAuth basic_auth = 2;
credentials.Unauthenticated unauthenticated = 3;
}
repeated string projects = 4;
bool skip_binaries = 5;
bool skip_archives = 6;
}
message Jenkins {
string endpoint = 1 [(validate.rules).string.uri_ref = true];
oneof credential {
credentials.BasicAuth basic_auth = 2;
credentials.Header header = 3;
credentials.Unauthenticated unauthenticated = 5;
}
bool insecure_skip_verify_tls = 4;
}
message Teams {
string endpoint = 1 [(validate.rules).string.uri_ref = true];
oneof credential {
string token = 2;
credentials.ClientCredentials authenticated = 3;
credentials.Oauth2 oauth = 7;
}
repeated string channels = 4;
repeated string ignore_list = 5;
repeated string team_ids = 6;
string tenant_id = 8;
}
message Syslog {
string protocol = 1;
string listen_address = 2;
string tlsCert = 3;
string tlsKey = 4;
string format = 5;
}
message Forager {
oneof credential {
credentials.Unauthenticated unauthenticated = 1;
}
repeated string domains = 2;
int64 max_depth = 3;
google.protobuf.Timestamp since = 4;
}
message SlackRealtime {
oneof credential {
credentials.SlackTokens tokens = 1;
}
}
message Sharepoint {
oneof credential {
credentials.Oauth2 oauth = 1;
}
string site_url = 2;
bool include_versions = 3;
bool include_comments = 4;
bool include_attachments = 5;
}
message AzureRepos {
string endpoint = 1 [(validate.rules).string.uri_ref = true];
oneof credential {
string token = 2;
credentials.Oauth2 oauth = 3;
}
repeated string repositories = 4;
repeated string organizations = 5;
repeated string projects = 6;
bool include_forks = 7;
repeated string ignore_repos = 8;
repeated string include_repos = 9;
repeated string include_projects = 10;
repeated string ignore_projects = 11;
bool skip_binaries = 12;
bool skip_archives = 13;
}
message Postman {
oneof credential {
credentials.Unauthenticated unauthenticated = 1;
string token = 2;
}
repeated string workspaces = 3;
repeated string collections = 4;
repeated string environments = 5;
repeated string exclude_collections = 6;
repeated string exclude_environments = 7;
repeated string include_collections = 8;
repeated string include_environments = 9;
repeated string detector_keywords = 10;
repeated string workspace_paths = 11;
repeated string collection_paths = 12;
repeated string environment_paths = 13;
}
message Webhook {
string listen_address = 1 [(validate.rules).string.hostname = true];
oneof credential {
credentials.Header header = 2;
}
oneof variant {
Vector vector = 4;
}
}
message Vector {
string locator_field = 1;
string link_format = 2;
}
message Elasticsearch {
repeated string nodes = 1;
string username = 2;
string password = 3;
string cloud_id = 4;
string api_key = 5;
string service_token = 6;
string index_pattern = 7;
string query_json = 8;
string since_timestamp = 9;
bool best_effort_scan = 10;
}
message Sentry {
string endpoint = 1;
oneof credential {
string auth_token = 2;
string dsn_key = 3;
string api_key = 4;
}
bool insecure_skip_verify_tls = 5;
string projects = 6;
}
message Stdin {}
message SlackContinuous {
string namespace = 1;
string project_id = 2;
}
message JSONEnumerator {
repeated string paths = 1;
}