public long putSubject(@NotNull Subject subject, long existingUniqueId) {
    final long newId;
    if (existingUniqueId == 0 || existingUniqueId == NOT_A_USER_ID) {
      newId = getNextID();
    } else {
      newId = existingUniqueId;
    }

    // we are saving all the subjects that's related to this uniqueId
    // we cannot immediately log out the old subject of this uniqueId because
    // it might already be bound to another thread and doing operations. If
    // we log out that subject immediately, that thread "authorize" would get null principal.
    synchronized (this) {
      List<Subject> subjects;
      if (!uniqueIdVsSubjects.containsKey(newId)) {
        secureLogger.debug("Subject of {} added.", newId);
        subjects = new ArrayList<>();
        uniqueIdVsSubjects.put(newId, subjects);
      } else {
        secureLogger.debug("Subject of {} replaced.", newId);
        subjects = uniqueIdVsSubjects.get(newId);
      }
      // always add the latest subject to the top of the list;
      subjects.add(0, subject);
    }
    return newId;
  }
This is per ServerConnection or per CacheClientProxy, corresponding to only one client
connection.
Credentials should usually be just one, only multiple in multi-user case.
geode-core/src/main/java/org/apache/geode/internal/cache/tier/sockets/ClientUserAuths.java