This is a pivot type query and this is usually done using filtered aggregation:
select string_agg(value, ',') filter (where key = 'key1') as key_1,
string_agg(value, ',') filter (where key = 'key2') as key_2,
string_agg(value, ',') filter (where key = 'key3') as key_3
It's not possible to make this dynamic.
A fundamental restriction of SQL is that the number, names and types of all columns of a query must be known before the query is executed.
Depending on how you process the result, aggregating everything into a JSON object might be an alternative:
select jsonb_object_agg(key, vals)
select key, jsonb_agg(value) as vals
group by key