Add policies yaml (#3464)

* Add policies yaml

* Add documentation and address review comments

* Amend documentation
This commit is contained in:
Tomas Touceda 2022-01-11 11:04:29 -03:00 committed by GitHub
parent 597144bfac
commit c662cd2b53
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 148 additions and 47 deletions

View File

@ -0,0 +1 @@
* Add a way to apply policy changes with fleetctl

View File

@ -24,10 +24,11 @@ type specMetadata struct {
}
type specGroup struct {
Queries []*fleet.QuerySpec
Teams []*fleet.TeamSpec
Packs []*fleet.PackSpec
Labels []*fleet.LabelSpec
Queries []*fleet.QuerySpec
Teams []*fleet.TeamSpec
Packs []*fleet.PackSpec
Labels []*fleet.LabelSpec
Policies []*fleet.PolicySpec
// This needs to be interface{} to allow for the patch logic. Otherwise we send a request that looks to the
// server like the user explicitly set the zero values.
AppConfig interface{}
@ -80,6 +81,13 @@ func specGroupFromBytes(b []byte) (*specGroup, error) {
}
specs.Labels = append(specs.Labels, labelSpec)
case fleet.PolicyKind:
var policySpec *fleet.PolicySpec
if err := yaml.Unmarshal(s.Spec, &policySpec); err != nil {
return nil, fmt.Errorf("unmarshaling "+kind+" spec: %w", err)
}
specs.Policies = append(specs.Policies, policySpec)
case fleet.AppConfigKind:
if specs.AppConfig != nil {
return nil, errors.New("config defined twice in the same file")
@ -178,6 +186,13 @@ func applyCommand() *cli.Command {
logf(c, "[+] applied %d labels\n", len(specs.Labels))
}
if len(specs.Policies) > 0 {
if err := fleetClient.ApplyPolicies(specs.Policies); err != nil {
return fmt.Errorf("applying policies: %w", err)
}
logf(c, "[+] applied %d policies\n", len(specs.Policies))
}
if len(specs.Packs) > 0 {
if err := fleetClient.ApplyPacks(specs.Packs); err != nil {
return fmt.Errorf("applying packs: %w", err)

View File

@ -4,6 +4,7 @@ import (
"context"
"database/sql"
"encoding/json"
"fmt"
"io/ioutil"
"os"
"testing"
@ -273,3 +274,57 @@ spec:
)
require.Nil(t, savedAppConfig)
}
func TestApplyPolicies(t *testing.T) {
_, ds := runServerWithMockedDS(t)
var appliedPolicySpecs []*fleet.PolicySpec
ds.ApplyPolicySpecsFunc = func(ctx context.Context, authorID uint, specs []*fleet.PolicySpec) error {
appliedPolicySpecs = specs
return nil
}
ds.TeamByNameFunc = func(ctx context.Context, name string) (*fleet.Team, error) {
if name == "Team1" {
return &fleet.Team{ID: 123}, nil
}
return nil, fmt.Errorf("unexpected team name!")
}
name := writeTmpYml(t, `---
apiVersion: v1
kind: policy
spec:
name: Is Gatekeeper enabled on macOS devices?
query: SELECT 1 FROM gatekeeper WHERE assessments_enabled = 1;
description: Checks to make sure that the Gatekeeper feature is enabled on macOS devices. Gatekeeper tries to ensure only trusted software is run on a mac machine.
resolution: "Run the following command in the Terminal app: /usr/sbin/spctl --master-enable"
platform: darwin
team: Team1
---
apiVersion: v1
kind: policy
spec:
name: Is disk encryption enabled on Windows devices?
query: SELECT 1 FROM bitlocker_info where protection_status = 1;
description: Checks to make sure that device encryption is enabled on Windows devices.
resolution: "Option 1: Select the Start button. Select Settings > Update & Security > Device encryption. If Device encryption doesn't appear, skip to Option 2. If device encryption is turned off, select Turn on. Option 2: Select the Start button. Under Windows System, select Control Panel. Select System and Security. Under BitLocker Drive Encryption, select Manage BitLocker. Select Turn on BitLocker and then follow the instructions."
platform: windows
---
apiVersion: v1
kind: policy
spec:
name: Is Filevault enabled on macOS devices?
query: SELECT 1 FROM disk_encryption WHERE user_uuid IS NOT AND filevault_status = on LIMIT 1;
description: Checks to make sure that the Filevault feature is enabled on macOS devices.
resolution: "Choose Apple menu > System Preferences, then click Security & Privacy. Click the FileVault tab. Click the Lock icon, then enter an administrator name and password. Click Turn On FileVault."
platform: darwin
`)
assert.Equal(t, "[+] applied 3 policies\n", runAppForTest(t, []string{"apply", "-f", name}))
assert.True(t, ds.ApplyPolicySpecsFuncInvoked)
assert.Len(t, appliedPolicySpecs, 3)
for _, p := range appliedPolicySpecs {
assert.NotEmpty(t, p.Platform)
}
assert.True(t, ds.TeamByNameFuncInvoked)
}

View File

@ -226,11 +226,6 @@ Use the stop and reset subcommands to manage the server and dependencies once st
return fmt.Errorf("failed to apply updated app config: %w", err)
}
fmt.Println("Applying Policies...")
if err := loadPolicies(client); err != nil {
fmt.Println("WARNING: Couldn't load policies:", err)
}
secrets, err := client.GetEnrollSecretSpec()
if err != nil {
return fmt.Errorf("Error retrieving enroll secret: %w", err)
@ -700,43 +695,6 @@ func killFromPIDFile(destDir string, pidFileName string, expectedExecName string
return nil
}
func loadPolicies(client *service.Client) error {
policies := []struct {
name, query, description, resolution, platform string
}{
{
"Is Gatekeeper enabled on macOS devices?",
"SELECT 1 FROM gatekeeper WHERE assessments_enabled = 1;",
"Checks to make sure that the Gatekeeper feature is enabled on macOS devices. Gatekeeper tries to ensure only trusted software is run on a mac machine.",
"Run the following command in the Terminal app: /usr/sbin/spctl --master-enable",
"darwin",
},
{
"Is disk encryption enabled on Windows devices?",
"SELECT 1 FROM bitlocker_info where protection_status = 1;",
"Checks to make sure that device encryption is enabled on Windows devices.",
"Option 1: Select the Start button. Select Settings > Update & Security > Device encryption. If Device encryption doesn't appear, skip to Option 2. If device encryption is turned off, select Turn on. Option 2: Select the Start button. Under Windows System, select Control Panel. Select System and Security. Under BitLocker Drive Encryption, select Manage BitLocker. Select Turn on BitLocker and then follow the instructions.",
"windows",
},
{
"Is Filevault enabled on macOS devices?",
`SELECT 1 FROM disk_encryption WHERE user_uuid IS NOT "" AND filevault_status = 'on' LIMIT 1;`,
"Checks to make sure that the Filevault feature is enabled on macOS devices.",
"Choose Apple menu > System Preferences, then click Security & Privacy. Click the FileVault tab. Click the Lock icon, then enter an administrator name and password. Click Turn On FileVault.",
"darwin",
},
}
for _, policy := range policies {
err := client.CreateGlobalPolicy(policy.name, policy.query, policy.description, policy.resolution, policy.platform)
if err != nil {
return fmt.Errorf("creating policy: %w", err)
}
}
return nil
}
func openBrowser(url string) error {
var cmd *exec.Cmd
switch runtime.GOOS {

View File

@ -633,3 +633,30 @@ spec:
query: SELECT * FROM apps WHERE path LIKE '/Applications/%' AND name IN ("Photoshop.app", "Adobe XD.app", "Sketch.app", "Illustrator.app") AND last_opened_time < (( SELECT unix_time FROM time ) - 2592000000000 );
purpose: Informational
contributors: DominusKelvin
---
apiVersion: v1
kind: policy
spec:
name: Is Gatekeeper enabled on macOS devices?
query: SELECT 1 FROM gatekeeper WHERE assessments_enabled = 1;
description: Checks to make sure that the Gatekeeper feature is enabled on macOS devices. Gatekeeper tries to ensure only trusted software is run on a mac machine.
resolution: "Run the following command in the Terminal app: /usr/sbin/spctl --master-enable"
platform: darwin
---
apiVersion: v1
kind: policy
spec:
name: Is disk encryption enabled on Windows devices?
query: SELECT 1 FROM bitlocker_info where protection_status = 1;
description: Checks to make sure that device encryption is enabled on Windows devices.
resolution: "Option 1: Select the Start button. Select Settings > Update & Security > Device encryption. If Device encryption doesn't appear, skip to Option 2. If device encryption is turned off, select Turn on. Option 2: Select the Start button. Under Windows System, select Control Panel. Select System and Security. Under BitLocker Drive Encryption, select Manage BitLocker. Select Turn on BitLocker and then follow the instructions."
platform: windows
---
apiVersion: v1
kind: policy
spec:
name: Is Filevault enabled on macOS devices?
query: SELECT 1 FROM disk_encryption WHERE user_uuid IS NOT “” AND filevault_status = on LIMIT 1;
description: Checks to make sure that the Filevault feature is enabled on macOS devices.
resolution: "Choose Apple menu > System Preferences, then click Security & Privacy. Click the FileVault tab. Click the Lock icon, then enter an administrator name and password. Click Turn On FileVault."
platform: darwin

View File

@ -21,6 +21,7 @@ Unlike the [Fleet REST API documentation](../01-Using-Fleet/03-REST-API.md), the
- [Retrieve live query results (standard WebSocket API)](#retrieve-live-query-results-standard-websocket-api)
- [Retrieve live query results (SockJS)](#retrieve-live-query-results-sockjs)
- [Run live query by name](#run-live-query-by-name)
- [Apply policies spec](#apply-policies-spec)
### Get queries spec
@ -1225,3 +1226,47 @@ o
}
]
```
### Apply policies spec
Creates and/or modifies the policies included in the specs list. To modify an existing policy, the name of the query included in `specs` must already be used by an existing policy. If a policy with the specified name doesn't exist in Fleet, a new policy will be created.
NOTE: when updating a policy, team and platform will be ignored.
`POST /api/v1/fleet/spec/policies`
#### Parameters
| Name | Type | In | Description |
| ----- | ---- | ---- | ----------------------------------------------------------------- |
| specs | list | body | **Required.** The list of the policies to be created or modified. |
#### Example
`POST /api/v1/fleet/spec/policies`
##### Request body
```json
{
"specs": [
{
"name": "new policy",
"description": "This will be a new policy because a policy with the name 'new policy' doesn't exist in Fleet.",
"query": "SELECT * FROM osquery_info",
"resolution": "some resolution steps here"
},
{
"name": "Is Filevault enabled on macOS devices?",
"query": "SELECT 1 FROM disk_encryption WHERE user_uuid IS NOT “” AND filevault_status = on LIMIT 1;",
"description": "Checks to make sure that the Filevault feature is enabled on macOS devices.",
"resolution": "Choose Apple menu > System Preferences, then click Security & Privacy. Click the FileVault tab. Click the Lock icon, then enter an administrator name and password. Click Turn On FileVault.",
"platform": "darwin"
}
]
}
```
##### Default response
`Status: 200`

View File

@ -386,7 +386,7 @@ func (ds *Datastore) TeamPolicy(ctx context.Context, teamID uint, policyID uint)
}
// ApplyPolicySpecs applies the given policy specs, creating new policies and updating the ones that
// already exist (a policy is identified by its name and the team it belongs to).
// already exist (a policy is identified by its name).
//
// NOTE: Similar to ApplyQueries, ApplyPolicySpecs will update the author_id of the policies
// that are updated.