Skip to content

Commit

Permalink
Add table okta_authentication_policy and fix rules column to populate…
Browse files Browse the repository at this point in the history
… correctly for Classic and Identity Engine accounts for the tables okta_password_policy, okta_idp_discovery_policy, and okta_signon_policy (#139)



Co-authored-by: Ved misra <[email protected]>
  • Loading branch information
ParthaI and misraved authored Aug 19, 2024
1 parent 381e46b commit d7244bf
Show file tree
Hide file tree
Showing 6 changed files with 341 additions and 36 deletions.
112 changes: 112 additions & 0 deletions docs/tables/okta_authentication_policy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
---
title: "Steampipe Table: okta_authentication_policy - Query Okta Authentication Policies using SQL"
description: "Allows users to query Okta Authentication Policies, providing details about the policies including their names, IDs, status, priority, and other related information."
---

# Table: okta_authentication_policy - Query Okta Authentication Policies using SQL

Okta Authentication Policies are a set of rules that specify the actions to be taken during user authentication based on a variety of conditions. These policies govern the authentication requirements users must meet before they are granted access to applications. They are an integral part of Okta's adaptive multi-factor authentication (MFA) and can be used to increase an organization's security.

## Table Usage Guide

The `okta_authentication_policy` table provides insights into Okta Authentication Policies. As a security analyst, you can leverage this table to understand the various authentication policies within your organization, including their priority, status, and the conditions under which they are applied. This information is crucial for auditing security measures and ensuring that your organization's authentication procedures are in line with best practices.

**Important Notes**
- This feature is only available as a part of Identity Engine. For more information please see [Authentication Policy](https://developer.okta.com/docs/reference/api/policy/#authentication-policy).

## Examples

### Basic info
Explore the priority-based organization of Okta authentication policies. This query can be used to assess the order of policies based on their priority, providing insights into the system's security measures and configurations.

```sql+postgres
select
name,
id,
created,
status,
priority,
system
from
okta_authentication_policy
order by
priority;
```

```sql+sqlite
select
name,
id,
created,
status,
priority,
system
from
okta_authentication_policy
order by
priority;
```

### List inactive sign-on policies
Explore which authentication policies are inactive. This is useful for maintaining security by identifying potential gaps in your active policies.

```sql+postgres
select
name,
id,
created,
status,
priority,
system
from
okta_authentication_policy
where
status = 'INACTIVE';
```

```sql+sqlite
select
name,
id,
created,
status,
priority,
system
from
okta_authentication_policy
where
status = 'INACTIVE';
```

### Get rules details for each sign-on policy
This query is useful to gain insights into each authentication policy's rules within your system. It provides a detailed view of the rules' names, systems, statuses, priorities, actions, and conditions, aiding in policy management and security assessment.

```sql+postgres
select
name,
id,
r -> 'name' as rule_name,
r -> 'system' as rule_system,
r -> 'status' as rule_status,
r -> 'priority' as rule_priority,
jsonb_pretty(r -> 'actions') as rule_actions,
jsonb_pretty(r -> 'conditions') as rule_conditions
from
okta_authentication_policy,
jsonb_array_elements(rules) as r;
```

```sql+sqlite
select
name,
id,
json_extract(r.value, '$.name') as rule_name,
json_extract(r.value, '$.system') as rule_system,
json_extract(r.value, '$.status') as rule_status,
json_extract(r.value, '$.priority') as rule_priority,
r.value as rule_actions,
r.value as rule_conditions
from
okta_authentication_policy,
json_each(rules) as r;
```
31 changes: 16 additions & 15 deletions okta/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,22 @@ func Plugin(ctx context.Context) *plugin.Plugin {
NewInstance: ConfigInstance,
},
TableMap: map[string]*plugin.Table{
"okta_app_assigned_group": tableOktaApplicationAssignedGroup(),
"okta_app_assigned_user": tableOktaApplicationAssignedUser(),
"okta_application": tableOktaApplication(),
"okta_auth_server": tableOktaAuthServer(),
"okta_device": tableOktaDevice(),
"okta_factor": tableOktaFactor(),
"okta_group": tableOktaGroup(),
"okta_idp_discovery_policy": tableOktaIdpDiscoveryPolicy(),
"okta_mfa_policy": tableOktaMfaPolicy(),
"okta_network_zone": tableOktaNetworkZone(),
"okta_password_policy": tableOktaPasswordPolicy(),
"okta_signon_policy": tableOktaSignonPolicy(),
"okta_trusted_origin": tableOktaTrustedOrigin(),
"okta_user": tableOktaUser(),
"okta_user_type": tableOktaUserType(),
"okta_app_assigned_group": tableOktaApplicationAssignedGroup(),
"okta_app_assigned_user": tableOktaApplicationAssignedUser(),
"okta_application": tableOktaApplication(),
"okta_auth_server": tableOktaAuthServer(),
"okta_authentication_policy": tableOktaAuthenticationPolicy(),
"okta_device": tableOktaDevice(),
"okta_factor": tableOktaFactor(),
"okta_group": tableOktaGroup(),
"okta_idp_discovery_policy": tableOktaIdpDiscoveryPolicy(),
"okta_mfa_policy": tableOktaMfaPolicy(),
"okta_network_zone": tableOktaNetworkZone(),
"okta_password_policy": tableOktaPasswordPolicy(),
"okta_signon_policy": tableOktaSignonPolicy(),
"okta_trusted_origin": tableOktaTrustedOrigin(),
"okta_user": tableOktaUser(),
"okta_user_type": tableOktaUserType(),
},
}

Expand Down
94 changes: 94 additions & 0 deletions okta/table_okta_authentication_policy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package okta

import (
"context"

"github.com/okta/okta-sdk-golang/v2/okta"
"github.com/okta/okta-sdk-golang/v2/okta/query"
"github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto"
"github.com/turbot/steampipe-plugin-sdk/v5/plugin"
"github.com/turbot/steampipe-plugin-sdk/v5/plugin/transform"
)

//// TABLE DEFINITION

func tableOktaAuthenticationPolicy() *plugin.Table {
return &plugin.Table{
Name: "okta_authentication_policy",
Description: "Okta Authentication Policy controls the manner in which a user is authenticated, including MFA requirements.",
List: &plugin.ListConfig{
Hydrate: listOktaAuthenticationPolicies,
},
Columns: []*plugin.Column{
// Top Columns
{Name: "name", Type: proto.ColumnType_STRING, Description: "Name of the Policy."},
{Name: "id", Type: proto.ColumnType_STRING, Description: "Identifier of the Policy."},
{Name: "description", Type: proto.ColumnType_STRING, Description: "Description of the Policy."},
{Name: "created", Type: proto.ColumnType_TIMESTAMP, Description: "Timestamp when the Policy was created."},

// Other Columns
{Name: "last_updated", Type: proto.ColumnType_TIMESTAMP, Description: "Timestamp when the Policy was last modified."},
{Name: "priority", Type: proto.ColumnType_INT, Description: "Priority of the Policy."},
{Name: "status", Type: proto.ColumnType_STRING, Description: "Status of the Policy: ACTIVE or INACTIVE."},
{Name: "system", Type: proto.ColumnType_BOOL, Description: "This is set to true on system policies, which cannot be deleted."},

// JSON Columns
{Name: "conditions", Type: proto.ColumnType_JSON, Description: "Conditions for Policy."},
{Name: "rules", Type: proto.ColumnType_JSON, Hydrate: getOktaPolicyRules, Transform: transform.FromValue(), Description: "Each Policy may contain one or more Rules. Rules, like Policies, contain conditions that must be satisfied for the Rule to be applied."},
{Name: "resource_mapping", Type: proto.ColumnType_JSON, Hydrate: getOktaPolicyAssociatedResources, Transform: transform.FromValue(), Description: "The resources that are mapped to the Policy."},

// Steampipe Columns
{Name: "title", Type: proto.ColumnType_STRING, Transform: transform.FromField("Name"), Description: titleDescription},
},
}
}

//// LIST FUNCTION

func listOktaAuthenticationPolicies(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) {
logger := plugin.Logger(ctx)
input := &query.Params{
Type: "ACCESS_POLICY",
}

client, err := Connect(ctx, d)
if err != nil {
logger.Error("listOktaAuthenticationPolicies", "connect_error", err)
return nil, err
}

policies, resp, err := client.Policy.ListPolicies(ctx, input)
if err != nil {
logger.Error("listOktaAuthenticationPolicies", "list_policies_error", err)
return nil, err
}

for _, policy := range policies {
d.StreamListItem(ctx, policy)

// Context can be cancelled due to manual cancellation or the limit has been hit
if d.RowsRemaining(ctx) == 0 {
return nil, nil
}
}

// paging
for resp.HasNextPage() {
var nextPolicySet []*okta.Policy
resp, err = resp.Next(ctx, &nextPolicySet)
if err != nil {
logger.Error("listOktaAuthenticationPolicies", "list_policies_paging_error", err)
return nil, err
}
for _, policy := range nextPolicySet {
d.StreamListItem(ctx, policy)

// Context can be cancelled due to manual cancellation or the limit has been hit
if d.RowsRemaining(ctx) == 0 {
return nil, nil
}
}
}

return nil, err
}
20 changes: 3 additions & 17 deletions okta/table_okta_idp_discovery_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ func tableOktaIdpDiscoveryPolicy() *plugin.Table {

// JSON Columns
{Name: "conditions", Type: proto.ColumnType_JSON, Description: "Conditions for Policy."},
{Name: "rules", Type: proto.ColumnType_JSON, Transform: transform.FromP(getpolicyRules, "rules"), Description: "Each Policy may contain one or more Rules. Rules, like Policies, contain conditions that must be satisfied for the Rule to be applied."},
{Name: "rules", Type: proto.ColumnType_JSON, Hydrate: getOktaPolicyRules, Transform: transform.FromValue(), Description: "Each Policy may contain one or more Rules. Rules, like Policies, contain conditions that must be satisfied for the Rule to be applied."},
{Name: "resource_mapping", Type: proto.ColumnType_JSON, Hydrate: getOktaPolicyAssociatedResources, Transform: transform.FromValue(), Description: "The resources that are mapped to the Policy."},

// Steampipe Columns
{Name: "title", Type: proto.ColumnType_STRING, Transform: transform.FromField("Name"), Description: titleDescription},
Expand All @@ -46,17 +47,14 @@ func listOktaIdpDiscoveryPolicies(ctx context.Context, d *plugin.QueryData, _ *p
logger := plugin.Logger(ctx)
client, err := Connect(ctx, d)

input := &query.Params{
Limit: 200,
}
input := &query.Params{}

if err != nil {
logger.Error("listOktaIdpDiscoveryPolicies", "connect_error", err)
return nil, err
}
if d.Table.Name == "okta_idp_discovery_policy" {
input.Type = "IDP_DISCOVERY"
input.Expand = "rules"
}
policies, resp, err := client.Policy.ListPolicies(ctx, input)
if err != nil {
Expand Down Expand Up @@ -90,15 +88,3 @@ func listOktaIdpDiscoveryPolicies(ctx context.Context, d *plugin.QueryData, _ *p
}
return nil, err
}

//// TRANSFORM FUNCTION

func getpolicyRules(_ context.Context, d *transform.TransformData) (interface{}, error) {
policy := d.HydrateItem.(*okta.AuthorizationServerPolicy)

if policy.Embedded != nil {
rules := policy.Embedded.(map[string]interface{})
return rules["rules"], nil
}
return nil, nil
}
4 changes: 2 additions & 2 deletions okta/table_okta_password_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,9 @@ func listPoliciesWithSettingsColumns() []*plugin.Column {

// JSON Columns
{Name: "conditions", Type: proto.ColumnType_JSON, Description: "Conditions for Policy."},
{Name: "rules", Type: proto.ColumnType_JSON, Transform: transform.FromField("Embedded.rules"), Description: "Each Policy may contain one or more Rules. Rules, like Policies, contain conditions that must be satisfied for the Rule to be applied."},
{Name: "rules", Type: proto.ColumnType_JSON, Hydrate: getOktaPolicyRules, Transform: transform.FromValue(), Description: "Each Policy may contain one or more Rules. Rules, like Policies, contain conditions that must be satisfied for the Rule to be applied."},
{Name: "settings", Type: proto.ColumnType_JSON, Description: "Settings of the password policy."},
{Name: "resource_mapping", Type: proto.ColumnType_JSON, Hydrate: getOktaPolicyAssociatedResources, Transform: transform.FromValue(), Description: "The resources that are mapped to the Policy."},

// Steampipe Columns
{Name: "title", Type: proto.ColumnType_STRING, Transform: transform.FromField("Name"), Description: titleDescription},
Expand All @@ -58,7 +59,6 @@ func listPolicies(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateDat
return nil, err
}

input.Expand = "rules"
switch d.Table.Name {
case "okta_password_policy":
input.Type = "PASSWORD"
Expand Down
Loading

0 comments on commit d7244bf

Please sign in to comment.