If you need to remove users or groups from documents, folder or custom objects in a bulk you can use the following sweep action

importPackage(java.lang);
importClass(java.lang.System);
importPackage(Packages.com.filenet.api.sweep);
importPackage(Packages.com.filenet.api.property);
importPackage(Packages.com.filenet.api.security);
importPackage(Packages.com.filenet.api.collection);
importPackage(Packages.com.filenet.api.core);
importPackage(Packages.com.filenet.api.constants);
importPackage(Packages.com.filenet.api.engine);
importPackage(Packages.com.filenet.api.exception);

// ============================================================
// Konfiguration
// ============================================================

// Name des Handlers (nur fuer Tracing)
var HANDLER_NAME = "RemoveAclSweepHandler";

// Trockenlauf:
//   true  = es wird nur protokolliert, was entfernt WUERDE (kein save)
//   false = Aenderungen werden gespeichert
// Empfehlung: erst mit DRY_RUN = true laufen lassen und das Trace pruefen.
var DRY_RUN = true;

// Grantees (User/Gruppen), deren DIREKTE Berechtigungen entfernt werden sollen.
// Die Schreibweise muss dem Rueckgabewert von get_GranteeName() entsprechen
// (i. d. R. realm-qualifiziert). Der Vergleich erfolgt case-insensitiv.
var granteesToRemove = [
    'p8os1archusers@p8.tta'    
];

// ============================================================
// Sweep-Einstiegspunkte
// ============================================================

// Policy-Sweep delegiert an dieselbe Logik wie der Custom-Sweep-Job.
function onPolicySweep(sweepObject, sweepPolicy, sweepItems) {
    onSweep(sweepObject, sweepItems);
}

function onSweep(sweepObject, sweepItems) {
    var hcc = HandlerCallContext.getInstance();
    hcc.traceDetail("Entering " + HANDLER_NAME + ".onSweep");
    hcc.traceDetail("sweepItems.length = " + sweepItems.length + (DRY_RUN ? "  [DRY_RUN]" : ""));

    var ii = 0;
    for (ii = 0; ii < sweepItems.length; ii++) {

        // Vor jeder Iteration pruefen, ob der Server heruntergefahren wird.
        if (hcc != null && hcc.isShuttingDown()) {
            throw new EngineRuntimeException(
                ExceptionCode.E_BACKGROUND_TASK_TERMINATED,
                HANDLER_NAME + " bricht ab, da der Server heruntergefahren wird");
        }

        var item = sweepItems[ii].getTarget();   // Document | Folder | CustomObject

        try {
            var removed = removeSecurityEntries(item, granteesToRemove, hcc);

            var note = (removed > 0)
                ? (removed + " ACE(s) entfernt" + (DRY_RUN ? " [DRY_RUN - nicht gespeichert]" : ""))
                : "keine passenden DIREKTEN ACEs gefunden";

            // PROCESSED auch bei 0 Treffern, damit das Item nicht als FAILED
            // erneut eingeplant wird.
            sweepItems[ii].setOutcome(SweepItemOutcome.PROCESSED, HANDLER_NAME + ": " + note);

        } catch (ex) {
            var emsg = (ex.rhinoException != null) ? ex.rhinoException.getMessage() : ("" + ex);
            sweepItems[ii].setOutcome(SweepItemOutcome.FAILED, HANDLER_NAME + ": " + emsg);
            hcc.traceDetail("FAILED " + emsg);
        }
    }

    hcc.traceDetail("Exiting " + HANDLER_NAME + ".onSweep");
}

// Properties, die der Sweep fuer die Items vorab laden soll.
function getRequiredProperties() {
    var pnames = ['Id', 'Permissions'];
    return pnames.toString();
}

// ============================================================
// Kernlogik
// ============================================================

function removeSecurityEntries(obj, granteesToRemove, hcc) {

    // get_Permissions() existiert auf Document, Folder und CustomObject.
    // Rhino loest die Methode anhand der konkreten Laufzeitklasse auf,
    // daher funktioniert derselbe Code fuer alle drei Objekttypen.
    var acl = obj.get_Permissions();   // AccessPermissionList

    if (hcc) {
        hcc.traceDetail("  Objekt-ID: " + obj.get_Id()
            + " | bestehende ACL-Eintraege: " + acl.size());
    }

    // Vergleichsmenge in Kleinschreibung aufbauen
    var removeSet = [];
    var r = 0;
    for (r = 0; r < granteesToRemove.length; r++) {
        removeSet.push(("" + granteesToRemove[r]).toLowerCase());
    }

    // Zu entfernende ACEs einsammeln (NICHT waehrend der Iteration loeschen).
    var toRemove = [];
    var iterator = acl.iterator();
    while (iterator.hasNext()) {
        var ace = iterator.next();                       // AccessPermission

        // WICHTIG: Nur DIREKT gesetzte Berechtigungen sind entfernbar.
        // Geerbte / Default / Template-ACEs werden serverseitig neu berechnet
        // und koennen nicht ueber das Objekt selbst entfernt werden.
        var src = ace.get_PermissionSource();            // PermissionSource
        if (src != null && !src.equals(PermissionSource.SOURCE_DIRECT)) {
            continue;
        }

        var grantee = ace.get_GranteeName();
        if (grantee == null) {
            continue;
        }

        if (removeSet.indexOf(("" + grantee).toLowerCase()) !== -1) {
            toRemove.push(ace);
            if (hcc) {
                hcc.traceDetail("  -> Treffer: " + grantee
                    + " (Type=" + ace.get_AccessType()
                    + ", Mask=" + ace.get_AccessMask() + ")");
            }
        }
    }

    if (toRemove.length === 0) {
        return 0;
    }

    // ACEs aus der Liste entfernen
    var k = 0;
    for (k = 0; k < toRemove.length; k++) {
        acl.remove(toRemove[k]);
    }

    if (DRY_RUN) {
        if (hcc) hcc.traceDetail("  [DRY_RUN] " + toRemove.length + " ACE(s) wuerden entfernt - kein save()");
        return toRemove.length;
    }

    // Geaenderte ACL zurueckschreiben und speichern.
    obj.set_Permissions(acl);
    obj.save(RefreshMode.NO_REFRESH);

    if (hcc) hcc.traceDetail("  " + toRemove.length + " ACE(s) entfernt und gespeichert");
    return toRemove.length;
}