@team-semicolon/semicolony-cli 4.18.51 → 4.18.52

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,44 @@
1
+ -- @schema-retarget: off
2
+ -- Hive cron v2 occurrence lease mutation privileges for the provider role.
3
+ -- Migration 154 remains the evidence-writer privilege boundary; this migration is
4
+ -- narrowly additive for lease acquisition and failed-occurrence release.
5
+ -- The migration runner supplies the transaction boundary; do not add one here.
6
+
7
+ DO $$
8
+ DECLARE
9
+ role_state record;
10
+ BEGIN
11
+ SELECT rolcanlogin, rolsuper, rolcreatedb, rolcreaterole,
12
+ rolinherit, rolreplication, rolbypassrls
13
+ INTO role_state
14
+ FROM pg_roles
15
+ WHERE rolname = 'sc_provider';
16
+
17
+ IF NOT FOUND THEN
18
+ RAISE EXCEPTION 'sc_provider role missing; migration 135 required';
19
+ END IF;
20
+
21
+ IF NOT role_state.rolcanlogin
22
+ OR role_state.rolsuper
23
+ OR role_state.rolcreatedb
24
+ OR role_state.rolcreaterole
25
+ OR role_state.rolinherit
26
+ OR role_state.rolreplication
27
+ OR role_state.rolbypassrls THEN
28
+ RAISE EXCEPTION 'sc_provider role attributes are unsafe';
29
+ END IF;
30
+ END $$;
31
+
32
+ REVOKE ALL PRIVILEGES
33
+ ON TABLE semicolony.cron_read_action_occurrence_leases
34
+ FROM sc_provider;
35
+
36
+ REVOKE ALL
37
+ ON FUNCTION semicolony.hive_cron_acquire_lease(text, text, text)
38
+ FROM PUBLIC, sc_app, sc_provider;
39
+ REVOKE ALL
40
+ ON FUNCTION semicolony.hive_cron_release_failed(text, text, text)
41
+ FROM PUBLIC, sc_app, sc_provider;
42
+
43
+ GRANT EXECUTE ON FUNCTION semicolony.hive_cron_acquire_lease(text, text, text) TO sc_provider;
44
+ GRANT EXECUTE ON FUNCTION semicolony.hive_cron_release_failed(text, text, text) TO sc_provider;
@@ -0,0 +1,47 @@
1
+ -- @schema-retarget: off
2
+ -- Hive cron v2 relay outbox mutation privilege for the provider role.
3
+ -- The migration runner supplies the transaction boundary; do not add one here.
4
+
5
+ DO $$
6
+ DECLARE
7
+ role_state record;
8
+ BEGIN
9
+ SELECT rolcanlogin, rolsuper, rolcreatedb, rolcreaterole,
10
+ rolinherit, rolreplication, rolbypassrls
11
+ INTO role_state
12
+ FROM pg_roles
13
+ WHERE rolname = 'sc_provider';
14
+
15
+ IF NOT FOUND THEN
16
+ RAISE EXCEPTION 'sc_provider role missing; migration 135 required';
17
+ END IF;
18
+
19
+ IF NOT role_state.rolcanlogin
20
+ OR role_state.rolsuper
21
+ OR role_state.rolcreatedb
22
+ OR role_state.rolcreaterole
23
+ OR role_state.rolinherit
24
+ OR role_state.rolreplication
25
+ OR role_state.rolbypassrls THEN
26
+ RAISE EXCEPTION 'sc_provider role attributes are unsafe';
27
+ END IF;
28
+ END $$;
29
+
30
+ REVOKE ALL PRIVILEGES
31
+ ON TABLE semicolony.cron_read_action_relay_outbox
32
+ FROM sc_provider;
33
+
34
+ REVOKE ALL
35
+ ON FUNCTION semicolony.hive_cron_put_outbox(text, text, text)
36
+ FROM PUBLIC, sc_app, sc_provider;
37
+ REVOKE ALL
38
+ ON FUNCTION semicolony.hive_cron_get_outbox(text, text, text)
39
+ FROM PUBLIC, sc_app, sc_provider;
40
+ REVOKE ALL
41
+ ON FUNCTION semicolony.hive_cron_complete_outbox(text, text, text, text, text)
42
+ FROM PUBLIC, sc_app, sc_provider;
43
+
44
+ GRANT EXECUTE ON FUNCTION semicolony.hive_cron_put_outbox(text, text, text) TO sc_provider;
45
+ GRANT EXECUTE ON FUNCTION semicolony.hive_cron_get_outbox(text, text, text) TO sc_provider;
46
+ GRANT EXECUTE ON FUNCTION semicolony.hive_cron_complete_outbox(text, text, text, text, text)
47
+ TO sc_provider;
@@ -0,0 +1,243 @@
1
+ -- @schema-retarget: off
2
+ -- Hive cron v2 append-only trusted configuration revisions.
3
+ -- This migration creates no configuration row and enables no cron job.
4
+ -- The migration runner supplies the transaction boundary; do not add one here.
5
+
6
+ CREATE OR REPLACE FUNCTION semicolony.hive_cron_valid_trusted_config_shape(p_action_kind text, p_payload jsonb)
7
+ RETURNS boolean
8
+ LANGUAGE plpgsql
9
+ IMMUTABLE
10
+ STRICT
11
+ SET search_path = pg_catalog
12
+ AS $$
13
+ DECLARE
14
+ endpoint jsonb;
15
+ endpoint_service_id text;
16
+ endpoint_origin text;
17
+ endpoint_service_ids text[] := ARRAY[]::text[];
18
+ endpoint_origins text[] := ARRAY[]::text[];
19
+ previous_endpoint_service_id text;
20
+ project_entry jsonb;
21
+ project_id text;
22
+ project_ids text[] := ARRAY[]::text[];
23
+ previous_project_id text;
24
+ BEGIN
25
+ IF pg_catalog.jsonb_typeof(p_payload) IS DISTINCT FROM 'object'
26
+ OR pg_catalog.octet_length(p_payload::text) > 65536
27
+ OR (p_payload::text COLLATE "C") ~* '(token|secret|password|authorization|credential)'
28
+ OR (p_payload::text COLLATE "C") ~* '-----BEGIN [^-]*(PRIVATE KEY|OPENSSH PRIVATE KEY)-----' THEN
29
+ RETURN false;
30
+ END IF;
31
+
32
+ IF p_action_kind = 'service-health-check' THEN
33
+ IF NOT (p_payload ? 'endpoints')
34
+ OR (p_payload - 'endpoints') <> '{}'::jsonb
35
+ OR pg_catalog.jsonb_typeof(p_payload->'endpoints') IS DISTINCT FROM 'array' THEN
36
+ RETURN false;
37
+ END IF;
38
+ IF pg_catalog.jsonb_array_length(p_payload->'endpoints') <> 4 THEN
39
+ RETURN false;
40
+ END IF;
41
+
42
+ FOR endpoint IN
43
+ SELECT value FROM pg_catalog.jsonb_array_elements(p_payload->'endpoints')
44
+ LOOP
45
+ IF pg_catalog.jsonb_typeof(endpoint) IS DISTINCT FROM 'object' THEN
46
+ RETURN false;
47
+ END IF;
48
+ IF NOT (endpoint ? 'serviceId')
49
+ OR NOT (endpoint ? 'origin')
50
+ OR (endpoint - 'serviceId' - 'origin') <> '{}'::jsonb
51
+ OR pg_catalog.jsonb_typeof(endpoint->'serviceId') IS DISTINCT FROM 'string'
52
+ OR pg_catalog.jsonb_typeof(endpoint->'origin') IS DISTINCT FROM 'string' THEN
53
+ RETURN false;
54
+ END IF;
55
+
56
+ endpoint_service_id := endpoint->>'serviceId';
57
+ endpoint_origin := endpoint->>'origin';
58
+ IF pg_catalog.char_length(endpoint_service_id) > 64
59
+ OR (endpoint_service_id COLLATE "C") !~ '^[a-z][a-z0-9]*(-[a-z0-9]+)*$'
60
+ OR endpoint_service_id = ANY(endpoint_service_ids)
61
+ OR (previous_endpoint_service_id IS NOT NULL
62
+ AND (endpoint_service_id COLLATE "C")
63
+ <= (previous_endpoint_service_id COLLATE "C"))
64
+ OR pg_catalog.char_length(endpoint_origin) > 261
65
+ OR (endpoint_origin COLLATE "C") !~ '^https://[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?(\.[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*\.[a-z]{2,63}$'
66
+ OR (endpoint_origin COLLATE "C") ~ '^https://([0-9]{1,3}\.){3}[0-9]{1,3}$'
67
+ OR (endpoint_origin COLLATE "C") ~ '(^https://|\.)xn--'
68
+ OR (endpoint_origin COLLATE "C") ~ '^https://(localhost|local|internal)$'
69
+ OR (endpoint_origin COLLATE "C") ~ '\.(localhost|local|internal)$'
70
+ OR endpoint_origin = ANY(endpoint_origins) THEN
71
+ RETURN false;
72
+ END IF;
73
+ previous_endpoint_service_id := endpoint_service_id;
74
+ endpoint_service_ids := pg_catalog.array_append(endpoint_service_ids, endpoint_service_id);
75
+ endpoint_origins := pg_catalog.array_append(endpoint_origins, endpoint_origin);
76
+ END LOOP;
77
+ RETURN true;
78
+ END IF;
79
+
80
+ IF p_action_kind = 'weekly-code-quality-scan' THEN
81
+ IF NOT (p_payload ? 'projectIds')
82
+ OR (p_payload - 'projectIds') <> '{}'::jsonb
83
+ OR pg_catalog.jsonb_typeof(p_payload->'projectIds') IS DISTINCT FROM 'array' THEN
84
+ RETURN false;
85
+ END IF;
86
+ IF pg_catalog.jsonb_array_length(p_payload->'projectIds') NOT BETWEEN 1 AND 32 THEN
87
+ RETURN false;
88
+ END IF;
89
+
90
+ FOR project_entry IN
91
+ SELECT value FROM pg_catalog.jsonb_array_elements(p_payload->'projectIds')
92
+ LOOP
93
+ IF pg_catalog.jsonb_typeof(project_entry) IS DISTINCT FROM 'string' THEN
94
+ RETURN false;
95
+ END IF;
96
+ project_id := project_entry #>> '{}';
97
+ IF pg_catalog.char_length(project_id) > 255
98
+ OR (project_id COLLATE "C") !~ '^[a-z0-9]([a-z0-9._-]{0,62}[a-z0-9])?(/[a-z0-9]([a-z0-9._-]{0,62}[a-z0-9])?)+$'
99
+ OR pg_catalog.lower(pg_catalog.right(project_id, 4)) = '.git'
100
+ OR pg_catalog.lower(pg_catalog.right(project_id, 5)) = '.atom'
101
+ OR 'land' = ANY(pg_catalog.regexp_split_to_array(project_id, '[/._-]'))
102
+ OR project_id = ANY(project_ids) THEN
103
+ RETURN false;
104
+ END IF;
105
+ IF previous_project_id IS NOT NULL
106
+ AND (project_id COLLATE "C") <= (previous_project_id COLLATE "C") THEN
107
+ RETURN false;
108
+ END IF;
109
+ previous_project_id := project_id;
110
+ project_ids := pg_catalog.array_append(project_ids, project_id);
111
+ END LOOP;
112
+ RETURN true;
113
+ END IF;
114
+
115
+ RETURN false;
116
+ END;
117
+ $$;
118
+
119
+ REVOKE ALL ON FUNCTION semicolony.hive_cron_valid_trusted_config_shape(text, jsonb)
120
+ FROM PUBLIC, sc_app, sc_provider;
121
+
122
+ CREATE TABLE IF NOT EXISTS semicolony.cron_read_action_trusted_config_revisions (
123
+ bot_id TEXT NOT NULL CHECK (bot_id = 'semi'),
124
+ job_id TEXT NOT NULL,
125
+ runtime_source TEXT NOT NULL CHECK (runtime_source = 'hive-cron-v2'),
126
+ action_kind TEXT NOT NULL CHECK (
127
+ btrim(action_kind) = action_kind
128
+ AND char_length(action_kind) BETWEEN 1 AND 128
129
+ AND action_kind !~ '[[:cntrl:]]'
130
+ ),
131
+ action_version INTEGER NOT NULL CHECK (action_version > 0),
132
+ action_contract_digest TEXT NOT NULL CHECK (
133
+ action_contract_digest ~ '^[a-f0-9]{64}$'
134
+ ),
135
+ config_revision INTEGER NOT NULL CHECK (config_revision > 0),
136
+ source_ref TEXT NOT NULL CHECK (
137
+ (source_ref COLLATE "C") ~ '^kb:[a-z0-9]([a-z0-9._-]{0,126}[a-z0-9])?/[a-z0-9]([a-z0-9._-]{0,126}[a-z0-9])?/[a-z0-9]([a-z0-9._-]{0,126}[a-z0-9])?$'
138
+ ),
139
+ config_payload JSONB NOT NULL CHECK (
140
+ jsonb_typeof(config_payload) = 'object'
141
+ AND octet_length(config_payload::text) <= 65536
142
+ ),
143
+ config_digest TEXT NOT NULL CHECK (
144
+ config_digest ~ '^sha256:[a-f0-9]{64}$'
145
+ ),
146
+ approved_by TEXT NOT NULL CHECK (
147
+ (approved_by COLLATE "C") ~ '^[a-z0-9]([a-z0-9._-]{0,126}[a-z0-9])?$'
148
+ ),
149
+ approved_at TIMESTAMPTZ NOT NULL,
150
+ created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
151
+ PRIMARY KEY (bot_id, job_id, runtime_source, config_revision),
152
+ FOREIGN KEY (bot_id, job_id, runtime_source)
153
+ REFERENCES semicolony.cron_capability_templates (bot_id, job_id, runtime_source),
154
+ CHECK (semicolony.hive_cron_valid_trusted_config_shape(action_kind, config_payload))
155
+ );
156
+
157
+ COMMENT ON TABLE semicolony.cron_read_action_trusted_config_revisions IS
158
+ 'Reviewed inert configuration revisions for Hive cron typed read actions; contains no credentials.';
159
+
160
+ COMMENT ON COLUMN semicolony.cron_read_action_trusted_config_revisions.action_contract_digest IS
161
+ 'Action contract reviewed with this revision; the loader compares it to the mutable current template.';
162
+
163
+ COMMENT ON COLUMN semicolony.cron_read_action_trusted_config_revisions.config_digest IS
164
+ 'SHA-256 of the canonical identity, action contract, revision, source reference, and payload envelope.';
165
+
166
+ CREATE OR REPLACE FUNCTION semicolony.hive_cron_get_trusted_config(p_job_id text)
167
+ RETURNS TABLE (
168
+ bot_id text,
169
+ job_id text,
170
+ runtime_source text,
171
+ action_kind text,
172
+ action_version integer,
173
+ action_contract_digest text,
174
+ config_revision integer,
175
+ source_ref text,
176
+ config_payload jsonb,
177
+ config_digest text,
178
+ approved_by text,
179
+ approved_at timestamptz,
180
+ created_at timestamptz,
181
+ current_action_kind text,
182
+ current_action_version integer,
183
+ current_action_contract_digest text
184
+ )
185
+ LANGUAGE sql
186
+ SECURITY DEFINER
187
+ SET search_path = pg_catalog
188
+ AS $$
189
+ SELECT config.bot_id,
190
+ config.job_id,
191
+ config.runtime_source,
192
+ config.action_kind,
193
+ config.action_version,
194
+ config.action_contract_digest,
195
+ config.config_revision,
196
+ config.source_ref,
197
+ config.config_payload,
198
+ config.config_digest,
199
+ config.approved_by,
200
+ config.approved_at,
201
+ config.created_at,
202
+ template.action_kind,
203
+ template.action_version,
204
+ template.action_contract_digest
205
+ FROM semicolony.cron_capability_templates AS template
206
+ JOIN LATERAL (
207
+ SELECT revision.bot_id,
208
+ revision.job_id,
209
+ revision.runtime_source,
210
+ revision.action_kind,
211
+ revision.action_version,
212
+ revision.action_contract_digest,
213
+ revision.config_revision,
214
+ revision.source_ref,
215
+ revision.config_payload,
216
+ revision.config_digest,
217
+ revision.approved_by,
218
+ revision.approved_at,
219
+ revision.created_at
220
+ FROM semicolony.cron_read_action_trusted_config_revisions AS revision
221
+ WHERE revision.bot_id = template.bot_id
222
+ AND revision.job_id = template.job_id
223
+ AND revision.runtime_source = template.runtime_source
224
+ ORDER BY revision.config_revision DESC
225
+ LIMIT 1
226
+ ) AS config ON true
227
+ WHERE template.bot_id = 'semi'
228
+ AND template.job_id = p_job_id
229
+ AND template.runtime_source = 'hive-cron-v2'
230
+ AND template.action_kind IS NOT NULL
231
+ AND template.action_version IS NOT NULL
232
+ AND template.action_contract_digest IS NOT NULL;
233
+ $$;
234
+
235
+ REVOKE ALL PRIVILEGES ON TABLE
236
+ semicolony.cron_read_action_trusted_config_revisions
237
+ FROM PUBLIC, sc_app, sc_provider;
238
+
239
+ REVOKE ALL ON FUNCTION semicolony.hive_cron_get_trusted_config(text)
240
+ FROM PUBLIC, sc_app, sc_provider;
241
+
242
+ GRANT EXECUTE ON FUNCTION semicolony.hive_cron_get_trusted_config(text)
243
+ TO sc_provider;