New: Boardroom MCP Engine!

Ready to put this into action?

Get the complete AI Integration Playbook β€” Practical AI implementation guide β€” prompt engineering, workflow automation, and ROI frameworks.

Article 131 Β· Part 13

Operate AI with Access Controls, Monitoring, and Recovery

The day after a successful demonstration is when responsibility becomes real.

By Randy Salars Β· Published

On this page
  1. Give the system an owner and a working agreement
  2. Enforce access before information reaches the model
  3. Observe outcomes that reveal useful problems
  4. Prepare an incident response that people can follow
  5. Know what your backup actually restores
  6. Run a content-recovery and access exercise
  7. Maintain the system as its surroundings change
  8. For students: practice the handoff, not just the demonstration
  9. A reusable prompt
  10. Practice: recover with the right boundaries intact

The day after a successful demonstration is when responsibility becomes real.

On Friday, the learning center's assistant answers questions correctly. On Monday, a staff member uploads a revised schedule. An older file is still in the search index, and a cached answer continues to give Saturday's former opening time.

A visitor reports the mistake. The volunteer at the desk knows the answer is wrong, but nobody knows who can pause the assistant. One person suggests deleting the index. Another suggests restoring last week's backup. A third changes the prompt.

Each action might change something. None yet establishes what happened or whether the next visitor will receive the correct answer.

Operating an AI system means giving people the information and authority to detect a problem, limit its effects, repair its cause, and verify recovery. The model is one component of that responsibility.

Give the system an owner and a working agreement

Before launch, identify the person responsible for the service and the people responsible for its sources and decisions. For a small project, one person may perform several roles. The roles still need names and clear boundaries.

Here is a fictional assignment for the learning center:

ResponsibilityAssigned personConcrete duty
Service ownerMaya, center coordinatorDefines supported uses and decides whether the service remains available
Source ownerLuis, program administratorConfirms which schedules and policies are current
Output reviewerJo, desk supervisorReviews disputed answers and tracks corrections
Incident responderMaya, with Jo as backupPauses affected functions and coordinates investigation
Change authorityMaya, after Luis verifies source changesAuthorizes release or restoration of a reviewed configuration

This is a teaching example, not a claim about a real organization. Replace each fictional name with an actual responsible person in your project.

Write a short operating agreement. State the supported hours, how users report errors, where the responder finds the controls, and what happens when the primary owner is unavailable. A system used only during a supervised class may have a simple agreement. An unattended service needs a response arrangement that matches its availability.

Give the responder a tested way to pause the affected workflow. If the same failing assistant is the only interface for stopping itself, you have a fragile arrangement.

Enforce access before information reaches the model

Authentication establishes identity. Authorization determines what that identity may do. A successful login does not grant access to every file, tool, or other user's records.

Enforce permissions in the application and data access layers. Use the identity established by the trusted session or service boundary; do not accept β€œI am the administrator” inside a prompt as an authorization decision. Apply checks to each requested resource and action, including cached results and downloads. OWASP recommends least privilege, denial by default, and permission validation on every request. OWASP Authorization Cheat Sheet

Draw the path of a record through your system: original file, extracted text, search index, retrieved passage, model input, answer, cache, export, and log. Decide who may access each copy. Restricting the original file does not automatically restrict an extracted passage stored elsewhere.

If two organizations use one service, test that a member of one cannot obtain the other's records by changing a document identifier. Also test the same person after their access is revoked. An old session or cached answer can otherwise become a forgotten route to information.

Give tools only the powers the workflow needs. A public information assistant usually does not need a credential that can edit every record. Keep secrets in the deployment's appropriate secret-management mechanism rather than in prompts, example files, or source documents.

Observe outcomes that reveal useful problems

A server can be running while the assistant gives bad answers. Monitor both technical operation and task quality.

Technical signals include failures, timeouts, queue delays, tool errors, and unexpected changes in resource use. Task signals include unsupported answers, missing citations, unresolved source conflicts, failed permission checks, and corrections reported by users.

A useful operational event identifies when an action occurred, which workflow and configuration handled it, what stage it reached, and how it ended. Use a request identifier to connect events from the same task. Keep source-version references when they are needed to investigate an answer.

Avoid turning the event log into an uncontrolled copy of everything the system sees. Passwords, access tokens, and sensitive document bodies should not appear in ordinary logs. Restrict log access and define retention. OWASP's logging guidance discusses both the information needed to investigate events and the data that should usually be excluded or protected. OWASP Logging Cheat Sheet

For the learning center, an event might record that request 204 used source collection 12 and returned an unresolved conflict. The responder can then inspect the authorized evidence through a controlled review process. Everyone who can see the dashboard does not need a copy of the visitor's full question.

Choose alerts that someone can act on. A permission-boundary failure should identify the affected function and its pause procedure. A rising rate of β€œno evidence found” should point the owner toward source availability and retrieval checks. Repeated alerts without a response owner merely create noise.

Prepare an incident response that people can follow

Separate detection, containment, investigation, repair, and restoration in the runbook. These activities can overlap, but each has a different purpose. An immediate pause may contain a problem before the underlying defect is understood.

NIST SP 800-61 Revision 3 places cybersecurity incident response within broader risk management and addresses preparation, detection, response, and recovery. Use its guidance where applicable to the system; a wrong schedule is an operational incident, while unauthorized disclosure may also be a security incident. NIST SP 800-61 Rev. 3

For the Monday schedule problem, use a concrete sequence:

  1. Confirm the observation. Record the reported answer, time, request identifier if available, and the current authoritative schedule.
  2. Contain the affected behavior. Pause automated schedule answers or direct users to a verified schedule while the problem is investigated.
  3. Preserve the useful evidence. Record source and configuration versions before replacing them. Restrict any sensitive incident material.
  4. Identify the cause. Check whether the source, index, retrieval, cache, or answer generation introduced the outdated fact.
  5. Repair and verify. Correct the responsible layer, invalidate affected derivatives, and rerun the schedule, exception, conflict, and access checks.
  6. Restore service deliberately. The owner confirms the evidence, resumes the function, and watches the relevant signals.

A status message should say what is affected, what users can do now, and when another update is expected. Avoid claiming that all records are correct merely because one example passed.

Afterward, record what allowed the defect through and what will change. The useful lesson may be a missing source-retirement step, not a need to remind someone to be more careful.

Know what your backup actually restores

A backup is evidence that data was copied. A restore test establishes whether a usable system can be recovered from it under the tested conditions.

List the state that matters: approved sources, configuration, necessary workflow records, access rules, deletion records, and references needed to reconcile external actions. Some indexes can be rebuilt from approved sources; others may contain information that requires separate preservation.

Define how much recent work you can afford to lose and how long the service can remain unavailable. These are often called the recovery point objective and recovery time objective. Write them in ordinary terms, such as β€œrecover the approved source collection without losing a day's edits” and β€œrestore the information service within two working hours.” Those are example goals, not measured achievements.

Do not blindly restore an old permission snapshot along with old content. Someone whose access was revoked yesterday should not regain it because a document was restored from Friday. Similarly, an older backup may contain a record that was subsequently marked for deletion. Recovery must apply the current access and deletion decisions before making restored information available.

For external effects, a backup alone is insufficient. Restoring a workflow database does not undo an order or email that already reached another system. Reconcile the original operation with the destination, following Article 121, before repeating work whose completion is uncertain.

Run a content-recovery and access exercise

This complete Python program simulates two groups with separate documents. It checks access before returning cached content, pauses reads, verifies a saved snapshot, restores earlier content, and preserves current revocations and deletion markers.

Save it as operations_lab.py and run python3 operations_lab.py. It uses only the Python standard library and temporary local files.

The test supplies trusted fictional identities directly. It does not implement login, network security, production backup storage, or a language model. Administrative methods are called by the local test harness. A real service must put those methods behind its trusted administrative boundary.

import hashlib
import json
from pathlib import Path
from tempfile import TemporaryDirectory


class Store:
    def __init__(self, documents, grants, deleted):
        self.documents = dict(documents)
        self.grants = grants
        self.deleted = deleted
        self.cache = {}
        self.events = []
        self.stopped = False

    def event(self, action, outcome):
        self.events.append({'sequence': len(self.events) + 1,
                            'action': action, 'outcome': outcome})

    def read(self, principal, document_id):
        if self.stopped:
            self.event('read', 'stopped')
            raise RuntimeError('Service paused')
        if (document_id not in self.grants.get(principal, set())
                or document_id in self.deleted
                or document_id not in self.documents):
            self.event('read', 'denied')
            raise PermissionError('Unavailable to this requester')
        key = (principal, document_id)
        if key in self.cache:
            self.event('read', 'cache_hit')
            return self.cache[key]
        self.cache[key] = self.documents[document_id]
        self.event('read', 'served')
        return self.cache[key]

    def replace_document(self, document_id, text):
        if document_id in self.deleted:
            raise ValueError('Document has a deletion marker')
        self.documents[document_id] = text
        self.cache.clear()
        self.event('update', 'completed')

    def pause(self):
        self.stopped = True
        self.event('pause', 'completed')

    def resume(self):
        self.stopped = False
        self.event('resume', 'completed')

    def backup(self, path):
        payload = json.dumps(self.documents, sort_keys=True).encode()
        path.write_bytes(payload)
        self.event('backup', 'completed')
        return hashlib.sha256(payload).hexdigest()

    def restore(self, path, expected_digest):
        if not self.stopped:
            raise RuntimeError('Pause before restore')
        payload = path.read_bytes()
        if hashlib.sha256(payload).hexdigest() != expected_digest:
            raise ValueError('Backup digest mismatch')
        candidate = json.loads(payload)
        if not isinstance(candidate, dict) or not all(
            isinstance(k, str) and isinstance(v, str)
            for k, v in candidate.items()
        ):
            raise ValueError('Invalid document snapshot')
        self.documents = {k: v for k, v in candidate.items()
                          if k not in self.deleted}
        self.cache.clear()
        self.event('restore', 'completed')


def expect_error(error_type, operation):
    try:
        operation()
    except error_type:
        return
    raise AssertionError('Expected ' + error_type.__name__)


def main():
    grants = {'north_reader': {'north:hours', 'north:contact'},
              'south_reader': {'south:hours'}}
    deleted = set()
    store = Store({'north:hours': '10:00-12:00',
                   'north:contact': 'Fictional Contact',
                   'south:hours': '14:00-16:00'}, grants, deleted)
    assert store.read('north_reader', 'north:hours') == '10:00-12:00'
    assert store.read('north_reader', 'north:hours') == '10:00-12:00'
    assert store.events[-1]['outcome'] == 'cache_hit'
    expect_error(PermissionError,
                 lambda: store.read('south_reader', 'north:hours'))
    expect_error(PermissionError,
                 lambda: store.read('unknown', 'north:hours'))
    with TemporaryDirectory() as directory:
        backup = Path(directory) / 'documents.json'
        digest = store.backup(backup)
        store.read('north_reader', 'north:contact')
        grants['north_reader'].remove('north:contact')
        expect_error(PermissionError,
                     lambda: store.read('north_reader', 'north:contact'))
        deleted.add('north:contact')
        store.replace_document('north:hours', 'INCORRECT HOURS')
        assert store.read('north_reader', 'north:hours') == 'INCORRECT HOURS'
        store.pause()
        expect_error(RuntimeError,
                     lambda: store.read('north_reader', 'north:hours'))
        expect_error(ValueError, lambda: store.restore(backup, 'wrong-digest'))
        assert store.documents['north:hours'] == 'INCORRECT HOURS'
        store.restore(backup, digest)
        assert store.stopped and not store.cache
        assert 'north:contact' not in store.documents
        assert 'north:contact' not in grants['north_reader']
        store.resume()
        assert store.read('north_reader', 'north:hours') == '10:00-12:00'
        expect_error(PermissionError,
                     lambda: store.read('north_reader', 'north:contact'))
        expect_error(PermissionError,
                     lambda: store.read('south_reader', 'north:hours'))
    assert all(set(event) == {'sequence', 'action', 'outcome'}
               for event in store.events)
    print('PASS: access separation, cached-access revocation, pause, '
          'snapshot verification, and content recovery')
    print('PASS: current grants and deletion markers survive content restore; '
          'events omit document text')


if __name__ == '__main__':
    main()

The program was executed for this manuscript and printed:

PASS: access separation, cached-access revocation, pause, snapshot verification, and content recovery
PASS: current grants and deletion markers survive content restore; events omit document text

Notice the ordering. A cache hit is available only after the current access check succeeds. The restore accepts document content without replacing the current grant map or deletion set. It empties the cache and leaves the service paused until the test explicitly resumes it.

The digest confirms that restored bytes match the digest retained by this test. It is not an authenticity guarantee if an attacker can replace both the file and its expected digest. Real backup integrity and access protection require controls outside this small program.

The exercise preserves the grant map and deletion set in the same running process. It does not prove recovery after losing the whole machine, nor does it erase the deleted record's bytes from the older backup. A full recovery test must recover current control records independently and apply the organization's backup-retention and deletion procedures.

The event list also has limited scope: it proves that these authored events omit document text. Its sequence numbers are sufficient for this local test, but an operating service needs protected storage, useful timestamps, request correlation, and a response when logging fails. Do not mistake the demonstration's small event list for a complete audit system.

Maintain the system as its surroundings change

Review source changes, permission changes, model changes, and dependency changes as distinct events. A new model does not update an old source. A corrected source does not automatically clear every answer cache.

For a small supervised project, a practical proposed routine is to check recent failures during each use session, review corrections weekly, and rerun the relevant evaluation after every meaningful change. Choose a cadence based on how often the system changes and what happens when it fails.

Keep a release record that connects the application, prompt, model, tool definitions, and source versions. Before resuming a restored configuration, check that its dependencies still work and that its sources remain authoritative. β€œPreviously working” and β€œcurrently appropriate” are different claims.

Also plan the end of the service. Name the person who can retire it, remove access, explain the replacement process, and handle retained data. A student project left connected after the course ends still needs an owner.

For students: practice the handoff, not just the demonstration

Use fictional records or teacher-approved public material. Assign one student as operator and another as reviewer. Have the reviewer introduce a known outdated fact into a test copy, then ask the operator to detect it, pause the affected function, restore the approved version, and explain the evidence for reopening.

A younger learner can perform the same exercise with paper cards: current source, retired source, access card, incident note, and corrected answer. The learning goal is understanding the decisions. Running a server is optional.

Keep each student's private work separate. Group membership does not automatically authorize uploading every member's notes or grades to a tool. Follow the actual assignment rules for allowed assistance and reporting.

End with a handoff: someone who did not build the project should be able to find its owner, identify its supported task, run the documented check, and stop it. Record any step that depended on the original builder remembering an unwritten detail.

A reusable prompt

Design an operating plan for the bounded AI workflow described below. Identify the service owner, source owner, reviewer, responder, and change authority. Map identity and permissions across sources, retrieval, caches, tools, exports, and logs. Specify observable failure signals, a tested pause mechanism, incident steps, and recovery checks. Explain how current revocations and deletion decisions remain effective after restoration. Separate proposed procedures from controls actually tested. Use the supplied requirements; identify missing facts rather than inventing them.

Practice: recover with the right boundaries intact

Run the program or perform the equivalent paper exercise. Introduce a source error, withdraw one person's access after a successful read, and restore the approved source. Verify that the corrected content returns to an authorized user while the withdrawn access remains denied.

Write a one-page incident record with the observation, containment action, cause, repair, recovery evidence, owner, and follow-up change. Mark which parts were simulated and which were executed.

Completion check: A named person can detect, contain, and recover the defined failure, and restoration preserves the current access decisions.

Stretch: Extend the exercise to a search index, exported answer, and separate cache. Track a deletion or access change across each copy, including what can and cannot be removed from historical backups.

Get the AI Dispatch

Weekly insights on ai & technology β€” delivered to your inbox. No spam, unsubscribe any time.

Want to choose specific topics? Customize your interests