Skip to content
RustPluginGenerator

OnGroupPermissionGranted

OnGroupPermissionGranted is called after a permission string has been successfully added to an Oxide group. It fires only when the permission was not already on the group, so it marks the moment a group gains a new capability.

Signature
void OnGroupPermissionGranted(string groupName, string permission)

Parameters

Hook parameters
ParameterTypeDescription
groupNamestringThe name of the Oxide permission group the permission was added to, as stored by the permission system (e.g. vip, admin).
permissionstringThe full permission string that was granted, typically plugin.action form such as myplugin.use.

Return value

The return value is ignored. Whatever you return, the permission grant has already been applied to the group and the original grant call proceeds normally.

How it works

Oxide invokes this hook inside Permission.GrantGroupPermission right after the permission is inserted into the group's permission set. If the group already had the permission, the method returns early and the hook never runs, so you get exactly one call per actual grant. It fires from oxide.grant group <group> <permission> in the server console, from RCON, and from any plugin calling permission.GrantGroupPermission.

Use groupName to look up the group or match it against a list you care about, and permission to inspect which capability was added. Revoking is a separate path, so you only see additions here; pair it with OnGroupPermissionRevoked for a complete audit.

This hook is called by Oxide itself, not from a patched game method, so it is not tied to any entity or player. There is no way to narrow dispatch by parameter type here: both parameters are plain strings, and there is no filter that stops the grant from happening. The grant is already committed when the hook runs, so treat it as a notification rather than a veto. Avoid heavy work inside the hook, and never assume the group still exists or that the permission string names a real plugin action.

Example plugin: Audit privileged group permission grants

GroupPermissionAudit.cs
using System.Linq;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;

namespace Oxide.Plugins
{
    [Info("Group Permission Audit", "RustPluginGenerator", "1.0.0")]
    [Description("Logs group permission grants for watched groups and sensitive permission strings")]
    public class GroupPermissionAudit : RustPlugin
    {
        private const string PermManage = "grouppermissionaudit.manage";

        private PluginConfig config;

        public class PluginConfig
        {
            [JsonProperty("Watched groups")]
            public List<string> WatchedGroups = new List<string> { "admin", "moderator" };

            [JsonProperty("Sensitive permissions")]
            public List<string> SensitivePermissions = new List<string> { "vanish.use", "teleport.use", "economics.balance" };
        }

        protected override void LoadDefaultConfig() => config = new PluginConfig();

        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                config = Config.ReadObject<PluginConfig>();
                if (config == null) throw new Exception();
            }
            catch
            {
                PrintWarning("Configuration file is invalid, using defaults");
                LoadDefaultConfig();
            }
            SaveConfig();
        }

        protected override void SaveConfig() => Config.WriteObject(config);

        private void Init()
        {
            permission.RegisterPermission(PermManage, this);
        }

        private void OnGroupPermissionGranted(string groupName, string permissionName)
        {
            if (string.IsNullOrEmpty(groupName) || string.IsNullOrEmpty(permissionName)) return;

            bool watched = config.WatchedGroups.Contains(groupName);
            bool sensitive = config.SensitivePermissions.Contains(permissionName);

            if (!watched && !sensitive) return;

            Interface.Oxide.LogInfo("[Group Permission Audit] {0} granted '{1}' to group '{2}'", DateTime.UtcNow.ToString("u"), permissionName, groupName);
        }

        [ChatCommand("gpaudit")]
        private void CmdAudit(BasePlayer player, string command, string[] args)
        {
            if (player == null) return;

            if (!permission.UserHasPermission(player.UserIDString, PermManage) && !player.IsAdmin)
            {
                player.ChatMessage("You do not have permission to use this command.");
                return;
            }

            if (args == null || args.Length < 1)
            {
                player.ChatMessage("Usage: /gpaudit watch <group> | /gpaudit list");
                return;
            }

            if (args[0].Equals("list", StringComparison.OrdinalIgnoreCase))
            {
                player.ChatMessage("Watched groups: " + string.Join(", ", config.WatchedGroups));
                return;
            }

            if (args[0].Equals("watch", StringComparison.OrdinalIgnoreCase) && args.Length >= 2)
            {
                string group = args[1].ToLower();
                if (config.WatchedGroups.Contains(group))
                {
                    player.ChatMessage("Group '" + group + "' is already watched.");
                    return;
                }
                config.WatchedGroups.Add(group);
                SaveConfig();
                player.ChatMessage("Now watching group '" + group + "' for permission grants.");
                return;
            }

            player.ChatMessage("Usage: /gpaudit watch <group> | /gpaudit list");
        }
    }
}

The plugin watches every group permission grant and writes a line to the server log when the group is on a configurable watch list or the permission is one of the configured high-risk strings. OnGroupPermissionGranted compares groupName against config.WatchedGroups and permission against the risky entries, then logs the grant with a timestamp so admins can see when a group gained something like a teleport or economy permission. A chat command lets an authorized admin add a group to the watch list at runtime, and the list is saved to the config file. Grants to groups nobody is watching are ignored, keeping log noise down.

Common use cases

  • Track who gains admin capabilities

    Log every grant on staff groups so you can review when a helper or moderator group picked up a new permission and by extension.

  • Notify on sensitive permissions

    Watch for strings like plugin teleport or economy permissions and print a warning to the console when they are added to any group.

  • Mirror grants to an external store

    Keep a data file copy of what each group was granted so a report command can list capabilities without scanning the whole permission registry.

Pitfalls

  • Only fires on new grants

    If the group already held the permission, Oxide returns before calling the hook, so do not rely on this hook to enumerate existing permissions at load time.

  • No veto possible

    The permission is already in the group's set when the hook runs and the return value is ignored, so blocking a grant from inside this hook will not work; wrap it in your own command instead.

  • Fires for plugin-driven grants too

    Other plugins that call permission.GrantGroupPermission trigger this hook as well, including ones running on timers or during initialization, so keep the handler cheap and avoid recursion on your own permission calls.

Build a plugin with OnGroupPermissionGranted

Describe what should happen and get a compiled plugin that uses this hook.

Prompt: Track who gains admin capabilities using the OnGroupPermissionGranted hook, with a config file and a permission
Generate this plugin

Edit the prompt on the next screen. 2 free plugins a month, no card.

Last updated Oct 26, 2026. Found a mistake? Email support@rustplugingenerator.com.

Build a plugin with OnGroupPermissionGranted

Generate