diff --git a/code/go/internal/validator/semantic/validate_var_groups.go b/code/go/internal/validator/semantic/validate_var_groups.go
new file mode 100644
index 000000000..07d28ef36
--- /dev/null
+++ b/code/go/internal/validator/semantic/validate_var_groups.go
@@ -0,0 +1,200 @@
+// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+// or more contributor license agreements. Licensed under the Elastic License;
+// you may not use this file except in compliance with the Elastic License.
+
+package semantic
+
+import (
+ "fmt"
+ "io/fs"
+ "path"
+
+ "gopkg.in/yaml.v3"
+
+ "github.com/elastic/package-spec/v3/code/go/internal/fspath"
+ "github.com/elastic/package-spec/v3/code/go/pkg/specerrors"
+)
+
+// ValidateVarGroups validates var_groups definitions in manifests.
+// It checks that:
+// - vars referenced in options[].vars exist in the manifest vars array
+// - var_group names are unique
+// - option names within each var_group are unique
+// - vars in a var_group must not have required: true (requirement is controlled by var_group)
+func ValidateVarGroups(fsys fspath.FS) specerrors.ValidationErrors {
+ // Validate main manifest.
+ d, err := fs.ReadFile(fsys, "manifest.yml")
+ if err != nil {
+ return specerrors.ValidationErrors{specerrors.NewStructuredErrorf("failed to read file \"%s\": %w", fsys.Path("manifest.yml"), err)}
+ }
+
+ var manifest varGroupsManifest
+ err = yaml.Unmarshal(d, &manifest)
+ if err != nil {
+ return specerrors.ValidationErrors{specerrors.NewStructuredErrorf("file \"%s\" is invalid: failed to parse manifest: %w", fsys.Path("manifest.yml"), err)}
+ }
+ errs := validateVarGroupsManifest(fsys.Path("manifest.yml"), manifest)
+
+ // Validate data stream manifests.
+ dataStreams, err := listDataStreams(fsys)
+ if err != nil {
+ return specerrors.ValidationErrors{specerrors.NewStructuredErrorf("failed to list data streams: %w", err)}
+ }
+ for _, ds := range dataStreams {
+ errs = append(errs, validateDataStreamVarGroups(fsys, path.Join("data_stream", ds, "manifest.yml"), manifest)...)
+ }
+
+ return errs
+}
+
+type varGroupsManifestVar struct {
+ Name string `yaml:"name"`
+ Required bool `yaml:"required"`
+}
+
+type varGroupOption struct {
+ Name string `yaml:"name"`
+ Vars []string `yaml:"vars"`
+}
+
+type varGroup struct {
+ Name string `yaml:"name"`
+ Required bool `yaml:"required"`
+ Options []varGroupOption `yaml:"options"`
+}
+
+type varGroupsManifest struct {
+ Vars []varGroupsManifestVar `yaml:"vars"`
+ VarGroups []varGroup `yaml:"var_groups"`
+ PolicyTemplates []struct {
+ Vars []varGroupsManifestVar `yaml:"vars"`
+ Inputs []struct {
+ Vars []varGroupsManifestVar `yaml:"vars"`
+ } `yaml:"inputs"`
+ } `yaml:"policy_templates"`
+}
+
+type varGroupsStream struct {
+ Title string `yaml:"title"`
+ Input string `yaml:"input"`
+ Vars []varGroupsManifestVar `yaml:"vars"`
+ VarGroups []varGroup `yaml:"var_groups"`
+}
+
+type varGroupsDataStreamManifest struct {
+ Streams []varGroupsStream `yaml:"streams"`
+}
+
+func validateVarGroupsManifest(filePath string, manifest varGroupsManifest) specerrors.ValidationErrors {
+ var errs specerrors.ValidationErrors
+
+ // Collect all available vars from package, policy templates, and inputs
+ var availableVars []varGroupsManifestVar
+ availableVars = append(availableVars, manifest.Vars...)
+ for _, template := range manifest.PolicyTemplates {
+ availableVars = append(availableVars, template.Vars...)
+ for _, input := range template.Inputs {
+ availableVars = append(availableVars, input.Vars...)
+ }
+ }
+
+ errs = append(errs, validateVarGroups(filePath, manifest.VarGroups, availableVars)...)
+
+ return errs
+}
+
+func validateDataStreamVarGroups(fsys fspath.FS, filePath string, pkgManifest varGroupsManifest) specerrors.ValidationErrors {
+ d, err := fs.ReadFile(fsys, filePath)
+ if err != nil {
+ // File might not exist, which is fine
+ return nil
+ }
+
+ var manifest varGroupsDataStreamManifest
+ err = yaml.Unmarshal(d, &manifest)
+ if err != nil {
+ return specerrors.ValidationErrors{specerrors.NewStructuredErrorf("file \"%s\" is invalid: failed to parse manifest: %w", fsys.Path(filePath), err)}
+ }
+
+ var errs specerrors.ValidationErrors
+
+ // Validate var_groups in each stream
+ for i, stream := range manifest.Streams {
+ if len(stream.VarGroups) == 0 {
+ continue
+ }
+
+ // Collect available vars from both package manifest and stream-level vars
+ var availableVars []varGroupsManifestVar
+ availableVars = append(availableVars, pkgManifest.Vars...)
+ availableVars = append(availableVars, stream.Vars...)
+
+ streamID := stream.Title
+ if streamID == "" {
+ streamID = stream.Input
+ }
+ if streamID == "" {
+ streamID = fmt.Sprintf("stream[%d]", i)
+ }
+
+ streamErrs := validateVarGroups(
+ fmt.Sprintf("%s (stream: %s)", fsys.Path(filePath), streamID),
+ stream.VarGroups,
+ availableVars,
+ )
+ errs = append(errs, streamErrs...)
+ }
+
+ return errs
+}
+
+func validateVarGroups(filePath string, varGroups []varGroup, availableVars []varGroupsManifestVar) specerrors.ValidationErrors {
+ var errs specerrors.ValidationErrors
+
+ // Build a map for quick var lookup
+ varMap := make(map[string]varGroupsManifestVar)
+ for _, v := range availableVars {
+ varMap[v.Name] = v
+ }
+
+ // Check for duplicate var_group names
+ seenGroupNames := make(map[string]bool)
+ for _, vg := range varGroups {
+ if seenGroupNames[vg.Name] {
+ errs = append(errs, specerrors.NewStructuredErrorf("file \"%s\" is invalid: duplicate var_group name %q", filePath, vg.Name))
+ }
+ seenGroupNames[vg.Name] = true
+
+ // Check for duplicate option names within each var_group
+ seenOptionNames := make(map[string]bool)
+ for _, opt := range vg.Options {
+ if seenOptionNames[opt.Name] {
+ errs = append(errs, specerrors.NewStructuredErrorf("file \"%s\" is invalid: duplicate option name %q in var_group %q", filePath, opt.Name, vg.Name))
+ }
+ seenOptionNames[opt.Name] = true
+
+ // Validate that referenced vars exist and check required consistency
+ for _, varName := range opt.Vars {
+ varDef, exists := varMap[varName]
+ if !exists {
+ errs = append(errs, specerrors.NewStructuredErrorf("file \"%s\" is invalid: var %q referenced in var_group %q option %q is not defined", filePath, varName, vg.Name, opt.Name))
+ continue
+ }
+
+ // Validate that vars in a var_group do not have required: true
+ // The requirement is controlled entirely by the var_group:
+ // - If var_group is required, all vars are implicitly required (inferred)
+ // - If var_group is not required, the entire group is optional
+ if varDef.Required {
+ if vg.Required {
+ errs = append(errs, specerrors.NewStructuredErrorf("file \"%s\" is invalid: var %q in required var_group %q should not have required: true (requirement is inferred from var_group)", filePath, varName, vg.Name))
+ } else {
+ errs = append(errs, specerrors.NewStructuredErrorf("file \"%s\" is invalid: var %q in non-required var_group %q should not have required: true (var_group is optional)", filePath, varName, vg.Name))
+ }
+ }
+ }
+ }
+ }
+
+ return errs
+}
diff --git a/code/go/internal/validator/semantic/validate_var_groups_test.go b/code/go/internal/validator/semantic/validate_var_groups_test.go
new file mode 100644
index 000000000..e8395ebc9
--- /dev/null
+++ b/code/go/internal/validator/semantic/validate_var_groups_test.go
@@ -0,0 +1,381 @@
+// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+// or more contributor license agreements. Licensed under the Elastic License;
+// you may not use this file except in compliance with the Elastic License.
+
+package semantic
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+ "gopkg.in/yaml.v3"
+)
+
+func TestValidateVarGroupsManifest(t *testing.T) {
+ cases := []struct {
+ title string
+ manifest string
+ errors []string
+ }{
+ {
+ title: "valid var_groups",
+ manifest: `
+vars:
+ - name: access_key_id
+ - name: secret_access_key
+ - name: role_arn
+var_groups:
+ - name: credential_type
+ options:
+ - name: direct_access_key
+ vars:
+ - access_key_id
+ - secret_access_key
+ - name: assume_role
+ vars:
+ - role_arn
+`,
+ },
+ {
+ title: "variable in policy template",
+ manifest: `
+vars:
+ - name: access_key_id
+policy_templates:
+ - vars:
+ - name: secret_access_key
+var_groups:
+ - name: credential_type
+ options:
+ - name: direct_access_key
+ vars:
+ - access_key_id
+ - secret_access_key
+`,
+ },
+ {
+ title: "variable in input",
+ manifest: `
+vars:
+ - name: access_key_id
+policy_templates:
+ - inputs:
+ - vars:
+ - name: secret_access_key
+var_groups:
+ - name: credential_type
+ options:
+ - name: direct_access_key
+ vars:
+ - access_key_id
+ - secret_access_key
+`,
+ },
+ {
+ title: "missing variable",
+ manifest: `
+vars:
+ - name: access_key_id
+var_groups:
+ - name: credential_type
+ options:
+ - name: direct_access_key
+ vars:
+ - access_key_id
+ - secret_access_key
+`,
+ errors: []string{
+ `file "manifest.yml" is invalid: var "secret_access_key" referenced in var_group "credential_type" option "direct_access_key" is not defined`,
+ },
+ },
+ {
+ title: "duplicate var_group name",
+ manifest: `
+vars:
+ - name: access_key_id
+var_groups:
+ - name: credential_type
+ options:
+ - name: direct_access_key
+ vars:
+ - access_key_id
+ - name: credential_type
+ options:
+ - name: another_option
+ vars:
+ - access_key_id
+`,
+ errors: []string{
+ `file "manifest.yml" is invalid: duplicate var_group name "credential_type"`,
+ },
+ },
+ {
+ title: "duplicate option name",
+ manifest: `
+vars:
+ - name: access_key_id
+ - name: secret_access_key
+var_groups:
+ - name: credential_type
+ options:
+ - name: direct_access_key
+ vars:
+ - access_key_id
+ - name: direct_access_key
+ vars:
+ - secret_access_key
+`,
+ errors: []string{
+ `file "manifest.yml" is invalid: duplicate option name "direct_access_key" in var_group "credential_type"`,
+ },
+ },
+ {
+ title: "no var_groups is valid",
+ manifest: `
+vars:
+ - name: access_key_id
+`,
+ },
+ {
+ title: "required var_group with non-required vars is valid",
+ manifest: `
+vars:
+ - name: access_key_id
+ - name: secret_access_key
+var_groups:
+ - name: credential_type
+ required: true
+ options:
+ - name: direct_access_key
+ vars:
+ - access_key_id
+ - secret_access_key
+`,
+ },
+ {
+ title: "non-required var_group with non-required vars is valid",
+ manifest: `
+vars:
+ - name: access_key_id
+ - name: secret_access_key
+var_groups:
+ - name: credential_type
+ required: false
+ options:
+ - name: direct_access_key
+ vars:
+ - access_key_id
+ - secret_access_key
+`,
+ },
+ {
+ title: "required var_group with required vars is invalid",
+ manifest: `
+vars:
+ - name: access_key_id
+ required: true
+ - name: secret_access_key
+var_groups:
+ - name: credential_type
+ required: true
+ options:
+ - name: direct_access_key
+ vars:
+ - access_key_id
+ - secret_access_key
+`,
+ errors: []string{
+ `file "manifest.yml" is invalid: var "access_key_id" in required var_group "credential_type" should not have required: true (requirement is inferred from var_group)`,
+ },
+ },
+ {
+ title: "non-required var_group with required vars is invalid",
+ manifest: `
+vars:
+ - name: access_key_id
+ required: true
+ - name: secret_access_key
+ required: true
+var_groups:
+ - name: credential_type
+ required: false
+ options:
+ - name: direct_access_key
+ vars:
+ - access_key_id
+ - secret_access_key
+`,
+ errors: []string{
+ `file "manifest.yml" is invalid: var "access_key_id" in non-required var_group "credential_type" should not have required: true (var_group is optional)`,
+ `file "manifest.yml" is invalid: var "secret_access_key" in non-required var_group "credential_type" should not have required: true (var_group is optional)`,
+ },
+ },
+ {
+ title: "default (non-required) var_group with non-required vars is valid",
+ manifest: `
+vars:
+ - name: access_key_id
+var_groups:
+ - name: credential_type
+ options:
+ - name: direct_access_key
+ vars:
+ - access_key_id
+`,
+ },
+ }
+
+ for _, c := range cases {
+ t.Run(c.title, func(t *testing.T) {
+ var manifest varGroupsManifest
+ err := yaml.Unmarshal([]byte(c.manifest), &manifest)
+ require.NoError(t, err)
+
+ errors := validateVarGroupsManifest("manifest.yml", manifest)
+ assert.Len(t, errors, len(c.errors))
+ for _, err := range errors {
+ assert.Contains(t, c.errors, err.Error())
+ }
+ })
+ }
+}
+
+func TestValidateVarGroups(t *testing.T) {
+ cases := []struct {
+ title string
+ varGroups []varGroup
+ availableVars []varGroupsManifestVar
+ errors []string
+ }{
+ {
+ title: "valid - all vars exist with required var_group",
+ varGroups: []varGroup{
+ {
+ Name: "auth_type",
+ Required: true,
+ Options: []varGroupOption{
+ {Name: "basic", Vars: []string{"username", "password"}},
+ {Name: "api_key", Vars: []string{"api_key"}},
+ },
+ },
+ },
+ availableVars: []varGroupsManifestVar{
+ {Name: "username", Required: false},
+ {Name: "password", Required: false},
+ {Name: "api_key", Required: false},
+ },
+ errors: nil,
+ },
+ {
+ title: "valid - all vars exist with non-required var_group and non-required vars",
+ varGroups: []varGroup{
+ {
+ Name: "auth_type",
+ Required: false,
+ Options: []varGroupOption{
+ {Name: "basic", Vars: []string{"username", "password"}},
+ },
+ },
+ },
+ availableVars: []varGroupsManifestVar{
+ {Name: "username", Required: false},
+ {Name: "password", Required: false},
+ },
+ errors: nil,
+ },
+ {
+ title: "missing var reference",
+ varGroups: []varGroup{
+ {
+ Name: "auth_type",
+ Required: true,
+ Options: []varGroupOption{
+ {Name: "basic", Vars: []string{"username", "password", "missing_var"}},
+ },
+ },
+ },
+ availableVars: []varGroupsManifestVar{
+ {Name: "username", Required: false},
+ {Name: "password", Required: false},
+ },
+ errors: []string{
+ `file "test.yml" is invalid: var "missing_var" referenced in var_group "auth_type" option "basic" is not defined`,
+ },
+ },
+ {
+ title: "duplicate var_group names",
+ varGroups: []varGroup{
+ {Name: "auth_type", Required: true, Options: []varGroupOption{{Name: "opt1", Vars: []string{}}}},
+ {Name: "auth_type", Required: true, Options: []varGroupOption{{Name: "opt2", Vars: []string{}}}},
+ },
+ availableVars: []varGroupsManifestVar{},
+ errors: []string{
+ `file "test.yml" is invalid: duplicate var_group name "auth_type"`,
+ },
+ },
+ {
+ title: "duplicate option names within var_group",
+ varGroups: []varGroup{
+ {
+ Name: "auth_type",
+ Required: true,
+ Options: []varGroupOption{
+ {Name: "basic", Vars: []string{}},
+ {Name: "basic", Vars: []string{}},
+ },
+ },
+ },
+ availableVars: []varGroupsManifestVar{},
+ errors: []string{
+ `file "test.yml" is invalid: duplicate option name "basic" in var_group "auth_type"`,
+ },
+ },
+ {
+ title: "required var_group with required var is invalid",
+ varGroups: []varGroup{
+ {
+ Name: "auth_type",
+ Required: true,
+ Options: []varGroupOption{
+ {Name: "basic", Vars: []string{"username"}},
+ },
+ },
+ },
+ availableVars: []varGroupsManifestVar{
+ {Name: "username", Required: true},
+ },
+ errors: []string{
+ `file "test.yml" is invalid: var "username" in required var_group "auth_type" should not have required: true (requirement is inferred from var_group)`,
+ },
+ },
+ {
+ title: "non-required var_group with required var is invalid",
+ varGroups: []varGroup{
+ {
+ Name: "auth_type",
+ Required: false,
+ Options: []varGroupOption{
+ {Name: "basic", Vars: []string{"username"}},
+ },
+ },
+ },
+ availableVars: []varGroupsManifestVar{
+ {Name: "username", Required: true},
+ },
+ errors: []string{
+ `file "test.yml" is invalid: var "username" in non-required var_group "auth_type" should not have required: true (var_group is optional)`,
+ },
+ },
+ }
+
+ for _, c := range cases {
+ t.Run(c.title, func(t *testing.T) {
+ errors := validateVarGroups("test.yml", c.varGroups, c.availableVars)
+ assert.Len(t, errors, len(c.errors))
+ for _, err := range errors {
+ assert.Contains(t, c.errors, err.Error())
+ }
+ })
+ }
+}
diff --git a/code/go/internal/validator/spec.go b/code/go/internal/validator/spec.go
index 7484e8df3..bbdbf7294 100644
--- a/code/go/internal/validator/spec.go
+++ b/code/go/internal/validator/spec.go
@@ -218,6 +218,7 @@ func (s Spec) rules(pkgType string, rootSpec spectypes.ItemSpec) validationRules
{fn: semantic.ValidateDimensionsPresent, types: []string{"integration"}, since: semver.MustParse("3.0.1")},
{fn: semantic.ValidateCapabilitiesRequired, since: semver.MustParse("2.10.0")}, // capabilities definition was added in spec version 2.10.0
{fn: semantic.ValidateRequiredVarGroups},
+ {fn: semantic.ValidateVarGroups, since: semver.MustParse("3.6.0")},
{fn: semantic.ValidateDocsStructure},
{fn: semantic.ValidateDeploymentModes, types: []string{"integration"}},
{fn: semantic.ValidateDurationVariables, since: semver.MustParse("3.5.0")},
diff --git a/code/go/pkg/validator/validator_test.go b/code/go/pkg/validator/validator_test.go
index 8407735dc..21efe0391 100644
--- a/code/go/pkg/validator/validator_test.go
+++ b/code/go/pkg/validator/validator_test.go
@@ -33,6 +33,7 @@ func TestValidateFile(t *testing.T) {
"good": {},
"good_v2": {},
"good_v3": {},
+ "good_var_groups": {},
"good_input": {},
"good_input_otel": {},
"good_content": {},
@@ -283,6 +284,30 @@ func TestValidateFile(t *testing.T) {
`required var "password" in optional group is not defined`,
},
},
+ "bad_var_groups_missing_var": {
+ "manifest.yml",
+ []string{
+ `var "non_existent_var" referenced in var_group "credential_type" option "direct_access_key" is not defined`,
+ },
+ },
+ "bad_var_groups_duplicate_name": {
+ "manifest.yml",
+ []string{
+ `duplicate option name "direct_access_key" in var_group "credential_type"`,
+ },
+ },
+ "bad_var_groups_required_var_in_required_group": {
+ "manifest.yml",
+ []string{
+ `var "access_key_id" in required var_group "credential_type" should not have required: true (requirement is inferred from var_group)`,
+ },
+ },
+ "bad_var_groups_required_var_in_optional_group": {
+ "manifest.yml",
+ []string{
+ `var "access_key_id" in non-required var_group "credential_type" should not have required: true (var_group is optional)`,
+ },
+ },
"bad_input_deployment_modes": {
"manifest.yml",
[]string{
diff --git a/spec/changelog.yml b/spec/changelog.yml
index 1c484a493..d4f0a1037 100644
--- a/spec/changelog.yml
+++ b/spec/changelog.yml
@@ -21,6 +21,11 @@
- description: Add support for deprecating packages or individual features (policy_templates, inputs, data_streams or variables).
type: enhancement
link: https://github.com/elastic/package-spec/pull/1053
+ # Pending on https://github.com/elastic/kibana/pull/249449
+ # Pending on https://github.com/elastic/integrations/pull/16985
+ - description: Add var_groups schema to support conditional variable groups for Cloud Connector integration.
+ type: enhancement
+ link: https://github.com/elastic/package-spec/issues/1054
# Pending on https://github.com/elastic/kibana/pull/251205
- description: Allow to set time series index mode in input packages.
type: enhancement
diff --git a/spec/integration/data_stream/manifest.spec.yml b/spec/integration/data_stream/manifest.spec.yml
index 39a3ff638..c16cf8183 100644
--- a/spec/integration/data_stream/manifest.spec.yml
+++ b/spec/integration/data_stream/manifest.spec.yml
@@ -601,6 +601,8 @@ spec:
$ref: "#/definitions/required_vars"
vars:
$ref: "#/definitions/vars"
+ var_groups:
+ $ref: "../../integration/manifest.spec.yml#/definitions/var_groups"
enabled:
description: Is stream enabled?
type: boolean
@@ -666,6 +668,8 @@ versions:
path: "/properties/deprecated"
- op: remove # remove deprecated field for vars
path: /definitions/vars/items/properties/deprecated
+ - op: remove
+ path: "/properties/streams/items/properties/var_groups" # removes var_groups from streams
- before: 3.5.0
patch:
# Require >=3.5.0 to use the duration variable type.
diff --git a/spec/integration/manifest.spec.yml b/spec/integration/manifest.spec.yml
index b334a25c2..ddb51b21e 100644
--- a/spec/integration/manifest.spec.yml
+++ b/spec/integration/manifest.spec.yml
@@ -524,6 +524,97 @@ spec:
required:
- since
- description
+ var_groups:
+ description: >
+ Defines mutually exclusive groups of variables. When an option is selected,
+ only the variables in that option's vars array are shown. The selected option
+ name is stored in the policy. Additional properties on options are allowed
+ for feature-specific extensions (e.g., Cloud Connector metadata).
+ type: array
+ items:
+ type: object
+ additionalProperties: false
+ properties:
+ name:
+ description: Unique identifier for this variable group selector.
+ type: string
+ pattern: '^[a-z][a-z0-9_]*$'
+ examples:
+ - credential_type
+ title:
+ description: Section header displayed in the UI (e.g., "Setup Access").
+ type: string
+ examples:
+ - Setup Access
+ selector_title:
+ description: Label for the dropdown selector (e.g., "Preferred method").
+ type: string
+ examples:
+ - Preferred method
+ description:
+ description: Help text explaining what this selector controls.
+ type: string
+ examples:
+ - Select how you want to authenticate with AWS.
+ required:
+ description: >
+ Whether a selection is required for this var_group. When true, Fleet UI
+ will require the user to select an option, and all variables within the
+ selected option are treated as required (inferred). When false (default),
+ the entire var_group is optional. Variables within a var_group must not
+ have required: true - the requirement is controlled entirely by this field.
+ type: boolean
+ default: false
+ options:
+ description: Available options. First option is the default.
+ type: array
+ minItems: 1
+ items:
+ type: object
+ additionalProperties: true
+ properties:
+ name:
+ description: Unique identifier (stored in policy when selected).
+ type: string
+ pattern: '^[a-z][a-z0-9_]*$'
+ examples:
+ - direct_access_key
+ - cloud_connectors
+ title:
+ description: Display title shown in the dropdown.
+ type: string
+ examples:
+ - Direct Access Keys
+ - Cloud Connector (recommended)
+ description:
+ description: Help text for this option.
+ type: string
+ examples:
+ - Use AWS access key ID and secret access key directly.
+ vars:
+ description: Variable names to display when this option is selected.
+ type: array
+ items:
+ type: string
+ examples:
+ - [access_key_id, secret_access_key]
+ hide_in_deployment_modes:
+ description: Deployment modes where this option is hidden.
+ type: array
+ items:
+ type: string
+ enum:
+ - default
+ - agentless
+ required:
+ - name
+ - title
+ - vars
+ required:
+ - name
+ - title
+ - selector_title
+ - options
properties:
format_version:
description: The version of the package specification format used by this package.
@@ -665,6 +756,17 @@ spec:
$ref: "./data_stream/manifest.spec.yml#/definitions/vars"
deprecated:
$ref: "#/definitions/deprecated"
+ hide_in_var_group_options:
+ description: >
+ Filter out specific var_group options for this input.
+ Keys are var_group names, values are arrays of option names to hide.
+ type: object
+ additionalProperties:
+ type: array
+ items:
+ type: string
+ examples:
+ - credential_type: [cloud_connectors]
required:
- type
- title
@@ -689,6 +791,8 @@ spec:
$ref: "#/definitions/screenshots"
vars:
$ref: "./data_stream/manifest.spec.yml#/definitions/vars"
+ var_groups:
+ $ref: "#/definitions/var_groups"
owner:
$ref: "#/definitions/owner"
agent:
@@ -751,6 +855,12 @@ versions:
path: "/properties/policy_templates/items/properties/deprecated"
- op: remove # remove deprecated definition
path: "/definitions/deprecated"
+ - op: remove
+ path: "/definitions/var_groups" # removes var_groups definition
+ - op: remove
+ path: "/properties/var_groups" # removes var_groups property
+ - op: remove
+ path: "/properties/policy_templates/items/properties/inputs/items/properties/hide_in_var_group_options" # removes hide_in_var_group_options from inputs
- before: 3.3.2
patch:
- op: remove
diff --git a/test/packages/bad_var_groups_duplicate_name/LICENSE.txt b/test/packages/bad_var_groups_duplicate_name/LICENSE.txt
new file mode 100644
index 000000000..f2d489e45
--- /dev/null
+++ b/test/packages/bad_var_groups_duplicate_name/LICENSE.txt
@@ -0,0 +1,7 @@
+Elastic License 2.0
+
+URL: https://www.elastic.co/licensing/elastic-license
+
+## Acceptance
+
+By using the software, you agree to all of the terms and conditions below.
diff --git a/test/packages/bad_var_groups_duplicate_name/changelog.yml b/test/packages/bad_var_groups_duplicate_name/changelog.yml
new file mode 100644
index 000000000..e00f88133
--- /dev/null
+++ b/test/packages/bad_var_groups_duplicate_name/changelog.yml
@@ -0,0 +1,6 @@
+# newer versions go on top
+- version: "0.0.1"
+ changes:
+ - description: Initial draft of the package
+ type: enhancement
+ link: https://github.com/elastic/integrations/pull/1
diff --git a/test/packages/bad_var_groups_duplicate_name/docs/README.md b/test/packages/bad_var_groups_duplicate_name/docs/README.md
new file mode 100644
index 000000000..fd73506b7
--- /dev/null
+++ b/test/packages/bad_var_groups_duplicate_name/docs/README.md
@@ -0,0 +1,4 @@
+# Bad Var Groups - Duplicate Names
+
+This test package has var_groups with duplicate option names.
+Should fail validation with an error about duplicate `direct_access_key` option name.
diff --git a/test/packages/bad_var_groups_duplicate_name/img/sample-logo.svg b/test/packages/bad_var_groups_duplicate_name/img/sample-logo.svg
new file mode 100644
index 000000000..6268dd88f
--- /dev/null
+++ b/test/packages/bad_var_groups_duplicate_name/img/sample-logo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/test/packages/bad_var_groups_duplicate_name/img/sample-screenshot.png b/test/packages/bad_var_groups_duplicate_name/img/sample-screenshot.png
new file mode 100644
index 000000000..d7a56a3ec
Binary files /dev/null and b/test/packages/bad_var_groups_duplicate_name/img/sample-screenshot.png differ
diff --git a/test/packages/bad_var_groups_duplicate_name/manifest.yml b/test/packages/bad_var_groups_duplicate_name/manifest.yml
new file mode 100644
index 000000000..a282dfe8d
--- /dev/null
+++ b/test/packages/bad_var_groups_duplicate_name/manifest.yml
@@ -0,0 +1,64 @@
+format_version: 3.6.0
+name: bad_var_groups_duplicate_name
+title: Bad Var Groups - Duplicate Names
+description: This package has var_groups with duplicate option names.
+version: 0.0.1
+type: integration
+source:
+ license: "Apache-2.0"
+conditions:
+ kibana:
+ version: '^8.10.0'
+ elastic:
+ subscription: 'basic'
+ agent:
+ version: '^9.1.0'
+vars:
+ - name: access_key_id
+ type: text
+ title: Access Key ID
+ show_user: true
+ secret: false
+ - name: secret_access_key
+ type: password
+ title: Secret Access Key
+ show_user: true
+ secret: true
+var_groups:
+ - name: credential_type
+ title: Setup Access
+ selector_title: Preferred method
+ description: Select how to authenticate.
+ options:
+ - name: direct_access_key
+ title: Direct Access Keys
+ vars:
+ - access_key_id
+ - secret_access_key
+ # Duplicate option name - should cause validation error
+ - name: direct_access_key
+ title: Another Direct Access Keys
+ vars:
+ - access_key_id
+policy_templates:
+ - name: sample
+ title: Sample
+ description: Sample policy template
+ inputs:
+ - type: httpjson
+ title: Collect via API
+ description: Collecting data
+ multi: false
+owner:
+ github: elastic/ecosystem
+ type: elastic
+screenshots:
+ - src: /img/sample-screenshot.png
+ title: Sample screenshot
+ size: 600x600
+ type: image/png
+icons:
+ - src: /img/sample-logo.svg
+ title: Sample logo
+ size: 32x32
+ type: image/svg+xml
diff --git a/test/packages/bad_var_groups_missing_var/LICENSE.txt b/test/packages/bad_var_groups_missing_var/LICENSE.txt
new file mode 100644
index 000000000..f2d489e45
--- /dev/null
+++ b/test/packages/bad_var_groups_missing_var/LICENSE.txt
@@ -0,0 +1,7 @@
+Elastic License 2.0
+
+URL: https://www.elastic.co/licensing/elastic-license
+
+## Acceptance
+
+By using the software, you agree to all of the terms and conditions below.
diff --git a/test/packages/bad_var_groups_missing_var/changelog.yml b/test/packages/bad_var_groups_missing_var/changelog.yml
new file mode 100644
index 000000000..e00f88133
--- /dev/null
+++ b/test/packages/bad_var_groups_missing_var/changelog.yml
@@ -0,0 +1,6 @@
+# newer versions go on top
+- version: "0.0.1"
+ changes:
+ - description: Initial draft of the package
+ type: enhancement
+ link: https://github.com/elastic/integrations/pull/1
diff --git a/test/packages/bad_var_groups_missing_var/docs/README.md b/test/packages/bad_var_groups_missing_var/docs/README.md
new file mode 100644
index 000000000..bc92ff2b2
--- /dev/null
+++ b/test/packages/bad_var_groups_missing_var/docs/README.md
@@ -0,0 +1,4 @@
+# Bad Var Groups - Missing Var Reference
+
+This test package has var_groups referencing a var that does not exist.
+Should fail validation with an error about `non_existent_var` not being defined.
diff --git a/test/packages/bad_var_groups_missing_var/img/sample-logo.svg b/test/packages/bad_var_groups_missing_var/img/sample-logo.svg
new file mode 100644
index 000000000..6268dd88f
--- /dev/null
+++ b/test/packages/bad_var_groups_missing_var/img/sample-logo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/test/packages/bad_var_groups_missing_var/img/sample-screenshot.png b/test/packages/bad_var_groups_missing_var/img/sample-screenshot.png
new file mode 100644
index 000000000..d7a56a3ec
Binary files /dev/null and b/test/packages/bad_var_groups_missing_var/img/sample-screenshot.png differ
diff --git a/test/packages/bad_var_groups_missing_var/manifest.yml b/test/packages/bad_var_groups_missing_var/manifest.yml
new file mode 100644
index 000000000..bc34d64a1
--- /dev/null
+++ b/test/packages/bad_var_groups_missing_var/manifest.yml
@@ -0,0 +1,61 @@
+format_version: 3.6.0
+name: bad_var_groups_missing_var
+title: Bad Var Groups - Missing Var Reference
+description: This package has var_groups referencing a var that does not exist.
+version: 0.0.1
+type: integration
+source:
+ license: "Apache-2.0"
+conditions:
+ kibana:
+ version: '^8.10.0'
+ elastic:
+ subscription: 'basic'
+ agent:
+ version: '^9.1.0'
+vars:
+ - name: access_key_id
+ type: text
+ title: Access Key ID
+ show_user: true
+ secret: false
+ - name: secret_access_key
+ type: password
+ title: Secret Access Key
+ show_user: true
+ secret: true
+var_groups:
+ - name: credential_type
+ title: Setup Access
+ selector_title: Preferred method
+ description: Select how to authenticate.
+ options:
+ - name: direct_access_key
+ title: Direct Access Keys
+ vars:
+ - access_key_id
+ - secret_access_key
+ # This var does not exist - should cause validation error
+ - non_existent_var
+policy_templates:
+ - name: sample
+ title: Sample
+ description: Sample policy template
+ inputs:
+ - type: httpjson
+ title: Collect via API
+ description: Collecting data
+ multi: false
+owner:
+ github: elastic/ecosystem
+ type: elastic
+screenshots:
+ - src: /img/sample-screenshot.png
+ title: Sample screenshot
+ size: 600x600
+ type: image/png
+icons:
+ - src: /img/sample-logo.svg
+ title: Sample logo
+ size: 32x32
+ type: image/svg+xml
diff --git a/test/packages/bad_var_groups_required_var_in_optional_group/LICENSE.txt b/test/packages/bad_var_groups_required_var_in_optional_group/LICENSE.txt
new file mode 100644
index 000000000..f2d489e45
--- /dev/null
+++ b/test/packages/bad_var_groups_required_var_in_optional_group/LICENSE.txt
@@ -0,0 +1,7 @@
+Elastic License 2.0
+
+URL: https://www.elastic.co/licensing/elastic-license
+
+## Acceptance
+
+By using the software, you agree to all of the terms and conditions below.
diff --git a/test/packages/bad_var_groups_required_var_in_optional_group/changelog.yml b/test/packages/bad_var_groups_required_var_in_optional_group/changelog.yml
new file mode 100644
index 000000000..e00f88133
--- /dev/null
+++ b/test/packages/bad_var_groups_required_var_in_optional_group/changelog.yml
@@ -0,0 +1,6 @@
+# newer versions go on top
+- version: "0.0.1"
+ changes:
+ - description: Initial draft of the package
+ type: enhancement
+ link: https://github.com/elastic/integrations/pull/1
diff --git a/test/packages/bad_var_groups_required_var_in_optional_group/docs/README.md b/test/packages/bad_var_groups_required_var_in_optional_group/docs/README.md
new file mode 100644
index 000000000..5a7f70522
--- /dev/null
+++ b/test/packages/bad_var_groups_required_var_in_optional_group/docs/README.md
@@ -0,0 +1,4 @@
+# Bad Var Groups - Required Var in Optional Group
+
+This test package has a var with `required: true` inside an optional var_group (required: false).
+Should fail validation because vars in a var_group should not have `required: true` - when the var_group is optional, the entire group is optional.
diff --git a/test/packages/bad_var_groups_required_var_in_optional_group/img/sample-logo.svg b/test/packages/bad_var_groups_required_var_in_optional_group/img/sample-logo.svg
new file mode 100644
index 000000000..6268dd88f
--- /dev/null
+++ b/test/packages/bad_var_groups_required_var_in_optional_group/img/sample-logo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/test/packages/bad_var_groups_required_var_in_optional_group/img/sample-screenshot.png b/test/packages/bad_var_groups_required_var_in_optional_group/img/sample-screenshot.png
new file mode 100644
index 000000000..d7a56a3ec
Binary files /dev/null and b/test/packages/bad_var_groups_required_var_in_optional_group/img/sample-screenshot.png differ
diff --git a/test/packages/bad_var_groups_required_var_in_optional_group/manifest.yml b/test/packages/bad_var_groups_required_var_in_optional_group/manifest.yml
new file mode 100644
index 000000000..05afc98a4
--- /dev/null
+++ b/test/packages/bad_var_groups_required_var_in_optional_group/manifest.yml
@@ -0,0 +1,63 @@
+format_version: 3.6.0
+name: bad_var_groups_required_var_in_optional_group
+title: Bad Var Groups - Required Var in Optional Group
+description: This package has a var with required:true inside an optional var_group.
+version: 0.0.1
+type: integration
+source:
+ license: "Apache-2.0"
+conditions:
+ kibana:
+ version: '^8.10.0'
+ elastic:
+ subscription: 'basic'
+ agent:
+ version: '^9.1.0'
+vars:
+ - name: access_key_id
+ type: text
+ title: Access Key ID
+ show_user: true
+ secret: false
+ # This var has required: true which is invalid in any var_group
+ required: true
+ - name: secret_access_key
+ type: password
+ title: Secret Access Key
+ show_user: true
+ secret: true
+var_groups:
+ - name: credential_type
+ title: Setup Access
+ selector_title: Preferred method
+ description: Select how to authenticate.
+ # var_group is optional (required: false), so vars should NOT have required: true
+ required: false
+ options:
+ - name: direct_access_key
+ title: Direct Access Keys
+ vars:
+ - access_key_id
+ - secret_access_key
+policy_templates:
+ - name: sample
+ title: Sample
+ description: Sample policy template
+ inputs:
+ - type: httpjson
+ title: Collect via API
+ description: Collecting data
+ multi: false
+owner:
+ github: elastic/ecosystem
+ type: elastic
+screenshots:
+ - src: /img/sample-screenshot.png
+ title: Sample screenshot
+ size: 600x600
+ type: image/png
+icons:
+ - src: /img/sample-logo.svg
+ title: Sample logo
+ size: 32x32
+ type: image/svg+xml
diff --git a/test/packages/bad_var_groups_required_var_in_required_group/LICENSE.txt b/test/packages/bad_var_groups_required_var_in_required_group/LICENSE.txt
new file mode 100644
index 000000000..f2d489e45
--- /dev/null
+++ b/test/packages/bad_var_groups_required_var_in_required_group/LICENSE.txt
@@ -0,0 +1,7 @@
+Elastic License 2.0
+
+URL: https://www.elastic.co/licensing/elastic-license
+
+## Acceptance
+
+By using the software, you agree to all of the terms and conditions below.
diff --git a/test/packages/bad_var_groups_required_var_in_required_group/changelog.yml b/test/packages/bad_var_groups_required_var_in_required_group/changelog.yml
new file mode 100644
index 000000000..e00f88133
--- /dev/null
+++ b/test/packages/bad_var_groups_required_var_in_required_group/changelog.yml
@@ -0,0 +1,6 @@
+# newer versions go on top
+- version: "0.0.1"
+ changes:
+ - description: Initial draft of the package
+ type: enhancement
+ link: https://github.com/elastic/integrations/pull/1
diff --git a/test/packages/bad_var_groups_required_var_in_required_group/docs/README.md b/test/packages/bad_var_groups_required_var_in_required_group/docs/README.md
new file mode 100644
index 000000000..eb0131d91
--- /dev/null
+++ b/test/packages/bad_var_groups_required_var_in_required_group/docs/README.md
@@ -0,0 +1,4 @@
+# Bad Var Groups - Required Var in Required Group
+
+This test package has a var with `required: true` inside a required var_group.
+Should fail validation because vars in a var_group should not have `required: true` - the requirement is inferred from the var_group.
diff --git a/test/packages/bad_var_groups_required_var_in_required_group/img/sample-logo.svg b/test/packages/bad_var_groups_required_var_in_required_group/img/sample-logo.svg
new file mode 100644
index 000000000..6268dd88f
--- /dev/null
+++ b/test/packages/bad_var_groups_required_var_in_required_group/img/sample-logo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/test/packages/bad_var_groups_required_var_in_required_group/img/sample-screenshot.png b/test/packages/bad_var_groups_required_var_in_required_group/img/sample-screenshot.png
new file mode 100644
index 000000000..d7a56a3ec
Binary files /dev/null and b/test/packages/bad_var_groups_required_var_in_required_group/img/sample-screenshot.png differ
diff --git a/test/packages/bad_var_groups_required_var_in_required_group/manifest.yml b/test/packages/bad_var_groups_required_var_in_required_group/manifest.yml
new file mode 100644
index 000000000..b5fb6c7a4
--- /dev/null
+++ b/test/packages/bad_var_groups_required_var_in_required_group/manifest.yml
@@ -0,0 +1,63 @@
+format_version: 3.6.0
+name: bad_var_groups_required_var_in_required_group
+title: Bad Var Groups - Required Var in Required Group
+description: This package has a var with required:true inside a required var_group.
+version: 0.0.1
+type: integration
+source:
+ license: "Apache-2.0"
+conditions:
+ kibana:
+ version: '^8.10.0'
+ elastic:
+ subscription: 'basic'
+ agent:
+ version: '^9.1.0'
+vars:
+ - name: access_key_id
+ type: text
+ title: Access Key ID
+ show_user: true
+ secret: false
+ # This var has required: true which is invalid in a required var_group
+ required: true
+ - name: secret_access_key
+ type: password
+ title: Secret Access Key
+ show_user: true
+ secret: true
+var_groups:
+ - name: credential_type
+ title: Setup Access
+ selector_title: Preferred method
+ description: Select how to authenticate.
+ # var_group is required, so vars should NOT have required: true
+ required: true
+ options:
+ - name: direct_access_key
+ title: Direct Access Keys
+ vars:
+ - access_key_id
+ - secret_access_key
+policy_templates:
+ - name: sample
+ title: Sample
+ description: Sample policy template
+ inputs:
+ - type: httpjson
+ title: Collect via API
+ description: Collecting data
+ multi: false
+owner:
+ github: elastic/ecosystem
+ type: elastic
+screenshots:
+ - src: /img/sample-screenshot.png
+ title: Sample screenshot
+ size: 600x600
+ type: image/png
+icons:
+ - src: /img/sample-logo.svg
+ title: Sample logo
+ size: 32x32
+ type: image/svg+xml
diff --git a/test/packages/good_var_groups/LICENSE.txt b/test/packages/good_var_groups/LICENSE.txt
new file mode 100644
index 000000000..f2d489e45
--- /dev/null
+++ b/test/packages/good_var_groups/LICENSE.txt
@@ -0,0 +1,7 @@
+Elastic License 2.0
+
+URL: https://www.elastic.co/licensing/elastic-license
+
+## Acceptance
+
+By using the software, you agree to all of the terms and conditions below.
diff --git a/test/packages/good_var_groups/changelog.yml b/test/packages/good_var_groups/changelog.yml
new file mode 100644
index 000000000..3202e0e08
--- /dev/null
+++ b/test/packages/good_var_groups/changelog.yml
@@ -0,0 +1,6 @@
+# newer versions go on top
+- version: "1.0.0-next"
+ changes:
+ - description: Initial draft of the package
+ type: enhancement
+ link: https://github.com/elastic/integrations/pull/1
diff --git a/test/packages/good_var_groups/data_stream/findings/agent/stream/aws-s3.yml.hbs b/test/packages/good_var_groups/data_stream/findings/agent/stream/aws-s3.yml.hbs
new file mode 100644
index 000000000..9df9e1f0e
--- /dev/null
+++ b/test/packages/good_var_groups/data_stream/findings/agent/stream/aws-s3.yml.hbs
@@ -0,0 +1,2 @@
+# Handlebars template for aws-s3 input
+bucket_arn: {{ bucket_arn }}
diff --git a/test/packages/good_var_groups/data_stream/findings/fields/base-fields.yml b/test/packages/good_var_groups/data_stream/findings/fields/base-fields.yml
new file mode 100644
index 000000000..20dbfcd1c
--- /dev/null
+++ b/test/packages/good_var_groups/data_stream/findings/fields/base-fields.yml
@@ -0,0 +1,15 @@
+- name: data_stream.type
+ type: constant_keyword
+ description: Data stream type.
+- name: data_stream.dataset
+ type: constant_keyword
+ description: Data stream dataset.
+- name: data_stream.namespace
+ type: constant_keyword
+ description: Data stream namespace.
+- name: "@timestamp"
+ type: date
+ description: Event timestamp.
+- name: message
+ type: text
+ description: Log message.
diff --git a/test/packages/good_var_groups/data_stream/findings/manifest.yml b/test/packages/good_var_groups/data_stream/findings/manifest.yml
new file mode 100644
index 000000000..303cd6a69
--- /dev/null
+++ b/test/packages/good_var_groups/data_stream/findings/manifest.yml
@@ -0,0 +1,80 @@
+title: Findings
+type: logs
+streams:
+ - input: aws-s3
+ template_path: aws-s3.yml.hbs
+ title: AWS S3 Findings
+ description: Collect findings from AWS S3 bucket
+ vars:
+ - name: bucket_arn
+ type: text
+ title: Bucket ARN
+ description: ARN of the S3 bucket
+ show_user: true
+ required: true
+ - name: access_key_id
+ type: text
+ title: Access Key ID
+ description: AWS access key ID for direct access
+ show_user: true
+ secret: false
+ - name: secret_access_key
+ type: password
+ title: Secret Access Key
+ description: AWS secret access key for direct access
+ show_user: true
+ secret: true
+ - name: session_token
+ type: password
+ title: Session Token
+ description: AWS session token for temporary credentials
+ show_user: true
+ secret: true
+ - name: role_arn
+ type: text
+ title: Role ARN
+ description: ARN of the IAM role to assume
+ show_user: true
+ - name: external_id
+ type: password
+ title: External ID
+ description: External ID for cross-account role assumption
+ show_user: true
+ secret: true
+ var_groups:
+ - name: credential_type
+ title: Setup Access
+ selector_title: Preferred method
+ description: >
+ Choose how to authenticate with AWS for collecting findings.
+ options:
+ - name: direct_access_key
+ title: Direct Access Keys
+ description: Use AWS access key ID and secret access key directly.
+ vars:
+ - access_key_id
+ - secret_access_key
+ - name: temporary_credentials
+ title: Temporary Credentials
+ description: Use temporary credentials with session token.
+ vars:
+ - access_key_id
+ - secret_access_key
+ - session_token
+ - name: assume_role
+ title: Assume Role
+ description: Assume an IAM role using role ARN.
+ vars:
+ - role_arn
+ - external_id
+ - name: cloud_connectors
+ title: Cloud Connector (recommended)
+ description: Use Elastic Cloud Connector for secure, agentless authentication.
+ vars:
+ - role_arn
+ - external_id
+ hide_in_deployment_modes:
+ - default
+ provider: aws
+ iac_template_url: >-
+ https://console.aws.amazon.com/cloudformation/home#/stacks/quickcreate?templateURL=https://elastic-cloud-connectors.s3.amazonaws.com/cloudformation-aws-connector.yml&stackName=Elastic-Cloud-Connector
diff --git a/test/packages/good_var_groups/docs/README.md b/test/packages/good_var_groups/docs/README.md
new file mode 100644
index 000000000..e90f1e883
--- /dev/null
+++ b/test/packages/good_var_groups/docs/README.md
@@ -0,0 +1,10 @@
+# Good Var Groups Package
+
+This test package demonstrates valid `var_groups` usage for conditional variable groups.
+
+## Features
+
+- Package-level `var_groups` with multiple authentication options
+- Cloud Connector option with `provider` and `iac_template_url` extensions
+- Input-level `hide_in_var_group_options` to filter options per input
+- Deployment mode filtering via `hide_in_deployment_modes`
diff --git a/test/packages/good_var_groups/img/sample-logo.svg b/test/packages/good_var_groups/img/sample-logo.svg
new file mode 100644
index 000000000..6268dd88f
--- /dev/null
+++ b/test/packages/good_var_groups/img/sample-logo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/test/packages/good_var_groups/img/sample-screenshot.png b/test/packages/good_var_groups/img/sample-screenshot.png
new file mode 100644
index 000000000..d7a56a3ec
Binary files /dev/null and b/test/packages/good_var_groups/img/sample-screenshot.png differ
diff --git a/test/packages/good_var_groups/manifest.yml b/test/packages/good_var_groups/manifest.yml
new file mode 100644
index 000000000..cf7fb4e11
--- /dev/null
+++ b/test/packages/good_var_groups/manifest.yml
@@ -0,0 +1,127 @@
+format_version: 3.6.0
+name: good_var_groups
+title: Good Var Groups Package
+description: This package demonstrates valid var_groups usage for conditional variable groups.
+version: 1.0.0-next
+type: integration
+source:
+ license: "Apache-2.0"
+conditions:
+ kibana:
+ version: '^8.10.0'
+ elastic:
+ subscription: 'basic'
+ agent:
+ version: '^9.1.0'
+vars:
+ - name: access_key_id
+ type: text
+ title: Access Key ID
+ show_user: true
+ secret: false
+ - name: secret_access_key
+ type: password
+ title: Secret Access Key
+ show_user: true
+ secret: true
+ - name: session_token
+ type: password
+ title: Session Token
+ show_user: true
+ secret: true
+ - name: role_arn
+ type: text
+ title: Role ARN
+ show_user: true
+ - name: external_id
+ type: password
+ title: External ID
+ show_user: true
+ secret: true
+var_groups:
+ - name: credential_type
+ title: Setup Access
+ selector_title: Preferred method
+ description: >
+ Utilize AWS Access Keys or assume role to set up access
+ for assessing your AWS environment's security posture.
+ required: true # User MUST select an authentication method
+ options:
+ - name: direct_access_key
+ title: Direct Access Keys
+ description: Use AWS access key ID and secret access key directly.
+ vars:
+ - access_key_id
+ - secret_access_key
+
+ - name: temporary_access_key
+ title: Temporary Access Keys
+ description: Use temporary credentials with session token.
+ vars:
+ - access_key_id
+ - secret_access_key
+ - session_token
+
+ - name: cloud_connectors
+ title: Cloud Connector (recommended)
+ description: Use Elastic Cloud Connector for secure, agentless authentication.
+ vars:
+ - role_arn
+ - external_id
+ hide_in_deployment_modes:
+ - default
+ # Cloud Connector-specific extensions (allowed by additionalProperties: true)
+ provider: aws
+ iac_template_url: "https://console.aws.amazon.com/cloudformation/home#/stacks/quickcreate?templateURL=https://elastic-cloud-connectors.s3.amazonaws.com/cloudformation-aws-connector.yml&stackName=Elastic-Cloud-Connector"
+
+ - name: assume_role
+ title: Assume Role
+ description: Assume an IAM role using role ARN.
+ vars:
+ - role_arn
+ hide_in_deployment_modes:
+ - agentless
+policy_templates:
+ - name: sample
+ title: Sample logs and metrics
+ description: Collect sample logs and metrics
+ data_streams:
+ - findings
+ inputs:
+ - type: httpjson
+ title: Collect via API
+ description: Collecting data from HTTP JSON API
+ multi: false
+ vars:
+ - name: url
+ type: url
+ title: API URL
+ show_user: true
+ required: true
+ - type: aws-s3
+ title: Collect from S3
+ description: Collecting logs from AWS S3 bucket
+ multi: false
+ # Hide cloud_connectors option for this input (aws-s3 doesn't support it)
+ hide_in_var_group_options:
+ credential_type:
+ - cloud_connectors
+ vars:
+ - name: bucket_name
+ type: text
+ title: S3 Bucket Name
+ show_user: true
+ required: true
+owner:
+ github: elastic/ecosystem
+ type: elastic
+screenshots:
+ - src: /img/sample-screenshot.png
+ title: Sample screenshot
+ size: 600x600
+ type: image/png
+icons:
+ - src: /img/sample-logo.svg
+ title: Sample logo
+ size: 32x32
+ type: image/svg+xml