To remove an object from a Collection, you can use the reject method. Here's how you can modify the getSSHKeysForHost method to remove the object inside the collection with the keyName equal to $key->name:
public function getSSHKeysForHost(): Collection
{
$sshKeys = collect();
$hostGroups = $this->groups;
foreach ($hostGroups as $hostGroup) {
$rules = $hostGroup->rules;
foreach ($rules as $rule) {
$keygroup = $rule->source;
$keys = $keyGroup->keys()->where('enabled', true)->get();
foreach ($keys as $key) {
switch ($rule->action) {
case ControlRuleAction::Deny:
$sshKeys = $sshKeys->reject(function ($sshKey) use ($key) {
return $sshKey['keyName'] === $key->name;
});
break;
case ControlRuleAction::Allow:
$content = explode(' ', $key->public, 3);
$content[2] = 'ssham: ' . $key->name;
$sshKeys->push([
'keyName' => $key->name,
'keyContent' => implode(' ', $content)
]);
break;
default:
// There is no more cases, but just in case (NOOP).
}
}
}
}
return $sshKeys;
}
As for a better approach, you could consider using a database to store the SSH keys and their relationships with the host groups. This would allow you to use more efficient queries to retrieve the allowed SSH keys for a given host. You could also consider using a dedicated SSH key management tool instead of building your own.