mirror of
https://github.com/empayre/fleet.git
synced 2024-11-06 08:55:24 +00:00
Add policies yaml (#3464)
* Add policies yaml * Add documentation and address review comments * Amend documentation
This commit is contained in:
parent
597144bfac
commit
c662cd2b53
1
changes/issue-2456-add-policies-yaml
Normal file
1
changes/issue-2456-add-policies-yaml
Normal file
@ -0,0 +1 @@
|
||||
* Add a way to apply policy changes with fleetctl
|
@ -28,6 +28,7 @@ type specGroup struct {
|
||||
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)
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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`
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user