In Ada95, the Unbounded_String type is often more flexible than the
String type because it is automatically resized as necessary.
However, don’t store especially sensitive secret values such as passwords
or secret keys in an Unbounded_String, since core dumps and page areas
might still hold them later.
Instead, use the String type for this data, lock it into memory
while it’s used, and overwrite the data as
soon as possible with some constant value such as (others => ' ').
Use the Ada pragma Inspection_Point on the object holding the secret
after erasing the memory.
That way, you can be certain that
the object containing the secret will really be erased
(and that the the overwriting won’t be optimized away).

Like many other languages,
Ada’s string types (including String and Unbounded_String)
can hold ASCII 0.
If that’s then passed to a C library (including a kernel), that can be
interpreted very differently by the library than the caller intended.

It’s common for beginning Ada programmers to believe that the
String type’s first index value is always 1, but this isn’t true if
the string is sliced.
Avoid this error.

It’s worth noting that SPARK is
a “high-integrity subset of the Ada programming language”;
SPARK users use a tool called the “SPARK Examiner” to check
conformance to SPARK rules, including flow analysis, and there are
various supports for full formal proof of the code if desired.
See the SPARK website for more
information.
To my knowledge, there are no OSS/FS SPARK tools.
If you’re storing passwords and private keys you should still
lock them into memory if appropriate
and overwrite them as soon as possible.
Note that SPARK is often used in environments where paging does not occur.