Skip to content

Commit

Permalink
feat: use the agent id in casbin rule
Browse files Browse the repository at this point in the history
[skip ci]
  • Loading branch information
adityathebe committed Nov 7, 2024
1 parent e29cc01 commit 19b6a2f
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 7 deletions.
9 changes: 3 additions & 6 deletions functions/postgrest.sql
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,9 @@ END $$;

DO $$
BEGIN
IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = 'postgrest_api') THEN
-- CREATE a ROLE that will own all views where we need to enforce RLS.
CREATE ROLE api_views_owner NOSUPERUSER NOBYPASSRLS;

GRANT SELECT ON ALL TABLES IN SCHEMA public TO api_views_owner;
END IF ;
-- CREATE a ROLE that will own all views where we need to enforce RLS.
CREATE ROLE api_views_owner NOSUPERUSER NOBYPASSRLS;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO api_views_owner;
END
$$;

21 changes: 20 additions & 1 deletion models/permission.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ type Permission struct {
UpdatedBy *uuid.UUID `json:"updated_by"`

// List of agent ids whose configs/components are accessible to a person when RLS is enabled
Agents pq.StringArray `json:"agents,omitempty"`
Agents pq.StringArray `json:"agents,omitempty" gorm:"type:[]text"`

// List of config/component tags a person is allowed access to when RLS is enabled
Tags types.JSONStringMap `json:"tags,omitempty"`
Expand Down Expand Up @@ -68,6 +68,25 @@ func (t *Permission) Condition() string {
rule = append(rule, fmt.Sprintf("r.obj.playbook != undefined && r.obj.playbook.id == %q", t.PlaybookID.String()))
}

if len(t.Agents) > 0 {
var agents []string
for _, agentID := range t.Agents {
agents = append(agents, fmt.Sprintf("'%s'", agentID))
}

rule = append(rule, fmt.Sprintf("r.obj.config != undefined && r.obj.config.agent_id in (%s)", strings.Join(agents, ",")))
rule = append(rule, fmt.Sprintf("r.obj.component != undefined && r.obj.component.agent_id in (%s)", strings.Join(agents, ",")))
rule = append(rule, fmt.Sprintf("r.obj.canary != undefined && r.obj.canary.agent_id in (%s)", strings.Join(agents, ",")))
}

// if len(t.Tags) > 0 {
// var tagsClause []string
// for _, agentID := range t.Tags {
// }
//
// rule = append(rule, strings.Join(tagsClause, " || "))
// }

return strings.Join(rule, " && ")
}

Expand Down
8 changes: 8 additions & 0 deletions models/permission_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"testing"

"github.com/google/uuid"
"github.com/lib/pq"
"github.com/samber/lo"
)

Expand Down Expand Up @@ -33,6 +34,13 @@ func TestPermission_Condition(t *testing.T) {
perm: Permission{},
expected: "",
},
{
name: "agents",
perm: Permission{
Agents: pq.StringArray([]string{"aws", "azure"}),
},
expected: "r.obj.config != undefined && r.obj.config.agent_id in ('aws','azure') && r.obj.component != undefined && r.obj.component.agent_id in ('aws','azure') && r.obj.canary != undefined && r.obj.canary.agent_id in ('aws','azure')",
},
}

for _, tt := range tests {
Expand Down
1 change: 1 addition & 0 deletions views/034_rls_enable.sql
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ ALTER TABLE components ENABLE ROW LEVEL SECURITY;
-- Policy config items
DROP POLICY IF EXISTS config_items_auth ON config_items;

-- TODO:: Don't re-add policy if it exists
CREATE POLICY config_items_auth ON config_items
FOR ALL TO postgrest_api, postgrest_anon
USING (tags::jsonb @> (current_setting('request.jwt.claims', TRUE)::json ->> 'tags')::jsonb
Expand Down

0 comments on commit 19b6a2f

Please sign in to comment.